Skip to content

Instantly share code, notes, and snippets.

@immmdreza
Last active January 20, 2024 13:22
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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.
}
@ZnZq
Copy link

ZnZq commented Jan 25, 2023

For .NET Core 3
You can use byte[] HmacSHA256(byte[] code, byte[] data) { using (HMACSHA256 hmac = new HMACSHA256(code)) { var hmBytes = hmac.ComputeHash(data); return hmBytes; } } instead of HMACSHA256.HashData

@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
}

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