I’m writing a backend for my mini-application and I’m faced with the problem of validating the data I receive. According to the official documentation (if I understood correctly), the hash is obtained from initDataUnsafe.hash, which is then validated against initData.
But when I tried to implement this, nothing works for me.
Here’s my C# data validation algorithm that doesn’t work. What could be the problem?
[Route("api/[controller]")]
[ApiController]
public class AuthController(IConfiguration configuration) : ControllerBase
{
private readonly string? _telegramToken = configuration["Tokens:TelegramToken"];
[HttpGet]
public IActionResult AuthUser(string initData, string hash)
{
if (ValidateData(_telegramToken, initData, hash))
{
return Ok(true);
}
return Unauthorized(false);
}
private static string ComputeHmacSha256(string key, string message)
{
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
private static bool ValidateData(string telegramToken, string initData, string hash)
{
var query = HttpUtility.ParseQueryString(initData);
var dataToCheck = query.AllKeys
.Where(k => k != "hash")
.OrderBy(k => k)
.Select(k => $"{k}={query[k]}")
.ToArray();
var dataCheckString = string.Join('n', dataToCheck);
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(telegramToken));
var computedHash = BitConverter.ToString(hmac.ComputeHash(Encoding.UTF8.GetBytes(dataCheckString))).Replace("-", "").ToLower();
var isValid = computedHash == hash.ToLower();
return isValid;
}
}