You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现Telegram登录时HMAC哈希校验结果不匹配问题

Telegram登录组件哈希校验不匹配解决方案

核心问题原因

你的代码存在两个致命逻辑错误,同时你使用的第三方NuGet包本身存在已知兼容bug,都会导致哈希计算结果和Telegram返回值不一致:

  • 校验字符串拼接逻辑错误:你硬编码了字段顺序,还手动给最后一个字段省略换行符。按照官方规则,需要排除hash字段后,将剩余所有字段按字段名的字典序升序排列,相邻key=value对之间用\n分隔,硬编码顺序、手动处理换行的写法在字段缺失、新增时会直接生成错误的拼接串。
  • 第三方包过时失效:你用的Telegram.Bot.Extensions.LoginWidget包早已停止维护,内部字段排序、编码逻辑存在bug,无法兼容Telegram后续新增的返回字段,不建议使用。
  • 额外容易踩的坑:如果对Telegram返回的字段值做了URL解码、转义、类型转换再拼接,也会导致哈希不匹配,必须使用原始返回值。

正确实现代码

using System.Security.Cryptography;
using System.Text;

public static bool VerifyTelegramAuth(IReadOnlyDictionary<string, string> authParams, string botToken)
{
    // 取出Telegram返回的哈希值
    if (!authParams.TryGetValue("hash", out string? telegramHash))
        return false;

    // 按规则拼接校验串:排除hash字段、按字段名字典序升序、\n分隔键值对
    var checkString = string.Join('\n', authParams
        .Where(kv => kv.Key != "hash")
        .OrderBy(kv => kv.Key, StringComparer.Ordinal)
        .Select(kv => $"{kv.Key}={kv.Value}"));

    // 计算密钥:BotToken的SHA256值
    byte[] secretKey;
    using (var sha256 = SHA256.Create())
    {
        secretKey = sha256.ComputeHash(Encoding.UTF8.GetBytes(botToken));
    }

    // 计算HMAC-SHA256
    byte[] hashBytes;
    using (var hmac = new HMACSHA256(secretKey))
    {
        hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(checkString));
    }

    // 转小写十六进制对比
    var computedHash = Convert.ToHexString(hashBytes).ToLowerInvariant();
    var isHashValid = computedHash == telegramHash.ToLowerInvariant();

    // 额外校验:auth_date超过24小时直接判定无效,防重放攻击
    if (isHashValid && authParams.TryGetValue("auth_date", out string? authDateStr) 
        && long.TryParse(authDateStr, out long authDate))
    {
        var expireTime = DateTimeOffset.FromUnixTimeSeconds(authDate).AddHours(24);
        return expireTime > DateTimeOffset.UtcNow;
    }

    return isHashValid;
}

测试注意事项

  • 不要用自己构造的模拟数据测试,必须用Telegram登录组件实际回调返回的完整原始参数测试
  • 所有参数值必须使用Telegram返回的原始字符串,不要做任何URL解码、HTML转义、格式转换
  • 如果你的站点是HTTPS,确保在Bot Father里设置的回调域和实际访问域名完全一致,否则返回的参数本身就是非法的

内容的提问来源于stack exchange,提问作者vuradzu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:55:02