Skip to content

Instantly share code, notes, and snippets.

@immmdreza
Last active October 29, 2024 10:12
Show Gist options
  • Save immmdreza/29415b29106d759371fbab23b67fff20 to your computer and use it in GitHub Desktop.
Save immmdreza/29415b29106d759371fbab23b67fff20 to your computer and use it in GitHub Desktop.
// Parse string initData from telegram.
var data = HttpUtility.ParseQueryString(initData);
// Put data in a alphabetically sorted dict.
var dataDict = new SortedDictionary<string, string>(
data.AllKeys.ToDictionary(x => x!, x => data[x]!),
StringComparer.Ordinal);
// Constant key to genrate secret key.
var constantKey = "WebAppData";
// https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app:
// Data-check-string is a chain of all received fields,
// sorted alphabetically.
// in the format key=<value>.
// with a line feed character ('\n', 0x0A) used as separator.
// e.g., 'auth_date=<auth_date>\nquery_id=<query_id>\nuser=<user>'
var dataCheckString = string.Join(
'\n', dataDict.Where(x => x.Key != "hash") // Hash should be removed.
.Select(x => $"{x.Key}={x.Value}")); // like auth_date=<auth_date> ..
// secrecKey is the HMAC-SHA-256 signature of the bot's token
// with the constant string WebAppData used as a key.
var secretKey = HMACSHA256.HashData(
Encoding.UTF8.GetBytes(constantKey), // WebAppData
Encoding.UTF8.GetBytes(_botConfig.BotToken)); // Bot's token
var generatedHash = HMACSHA256.HashData(
secretKey,
Encoding.UTF8.GetBytes(dataCheckString)); // data_check_string
// Convert received hash from telegram to a byte array.
var actualHash = Convert.FromHexString(dataDict["hash"]); // .NET 5.0
// Compare our hash with the one from telegram.
if (actualHash.SequenceEqual(generatedHash))
{
// Data from telegram.
}
@Gridiron
Copy link

Gridiron commented Jan 26, 2023

There is no way this code can work because you use HMACSHA256 for hashing of token for secret key instead of SHA256.

@immmdreza
Copy link
Author

immmdreza commented Jan 26, 2023

There is no way this code can work because you use HMACSHA256 for hashing of token for secret key instead of SHA256.

data_check_string = ...
secret_key = HMAC_SHA256(<bot_token>, "WebAppData")
if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) {
  // data is from Telegram
}

Telegram docs noticed that it should be HMAC_SHA256.

I’m not really sure that it’s working at the moment, but it was.

@Polaroid15
Copy link

@immmdreza Man! Thank you very much!

@immmdreza
Copy link
Author

@immmdreza Man! Thank you very much!
🙏

@nyatt9992
Copy link

data_check_string = ...
secret_key = SHA256(<bot_token>)
if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) {
// data is from Telegram
}

@stylophone
Copy link

stylophone commented Jul 15, 2024

Thanks for the code!

@layinka
Copy link

layinka commented Sep 27, 2024

Thanks, This really helped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment