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

Java实现Telegram哈希验证异常,求原因及SDK可用方法

Telegram哈希验证Java实现问题及SDK方案

问题背景

我在Java中无法完成Telegram哈希验证,现有可正常运行的JS示例:

function main() {
  var k = CryptoJS.HmacSHA256('k', 'WebAppData');
  console.log("k: " + k);

  var h = CryptoJS.HmacSHA256('data', k);
  console.log("h: " + h);
}

main();

输出结果:

"k: 3db03151d3fb2678c9fc0f24ee15817bfd1ff922a712a055f63066f875e43fc1"
"h: 9158b0aeb1e882c075ea46a0d5302cffba1a9b66b0df40f5f01eef614f7d9f94"

但使用Apache Commons的HmacUtils实现时:

var secretKey = new HmacUtils("HmacSHA256", "WebAppData").hmacHex("k");
var hash = new HmacUtils("HmacSHA256", secretKey).hmacHex("data");

生成的secretKey与JS一致,但最终hash结果不符:

secretKey: 3db03151d3fb2678c9fc0f24ee15817bfd1ff922a712a055f63066f875e43fc1
hash: 2c73ad3290e04a382b29edea6cb0ef4b1454592429336c32e98ad611452581b2

请问问题出在哪里?另外,rubenlagus的Telegram SDK是否有现成方法可避免手动实现该验证?


问题原因分析

JS代码中,第二次调用CryptoJS.HmacSHA256('data', k)时,k是HMAC生成的原始二进制哈希值,CryptoJS会直接用这个二进制数据作为密钥。

而你的Java代码中,把第一次生成的十六进制字符串secretKey直接传给了HmacUtils,此时HMAC会把这个字符串的UTF-8字节(而非原始哈希的二进制字节)作为密钥,导致最终哈希结果不一致。

修正后的Java实现

需要将十六进制字符串解码为原始字节数组,再作为密钥传入HmacUtils。可以使用Apache Commons Codec的Hex类来完成解码:

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.HmacUtils;

public class TelegramHashTest {
    public static void main(String[] args) {
        // 第一步生成密钥的十六进制字符串
        String secretKeyHex = new HmacUtils("HmacSHA256", "WebAppData").hmacHex("k");
        // 将十六进制字符串解码为原始字节数组
        byte[] secretKeyBytes = Hex.decodeHex(secretKeyHex);
        // 使用原始字节数组作为密钥生成最终哈希
        String hash = new HmacUtils("HmacSHA256", secretKeyBytes).hmacHex("data");
        
        System.out.println("secretKey: " + secretKeyHex);
        System.out.println("hash: " + hash); // 此时结果会和JS一致
    }
}

rubenlagus的Telegram SDK相关支持

rubenlagus的TelegramBots库(即你说的Telegram SDK)提供了现成的工具类来处理Telegram WebApp的哈希验证,无需手动实现HMAC逻辑。

例如,org.telegram.telegrambots.meta.api.objects.WebAppData类配合TelegramWebAppUtils,可以直接传入initData和机器人令牌,完成哈希验证。示例大致如下:

import org.telegram.telegrambots.meta.api.objects.WebAppData;
import org.telegram.telegrambots.meta.util.TelegramWebAppUtils;

public class WebAppValidation {
    public static void main(String[] args) {
        String botToken = "你的机器人令牌";
        String initData = "从WebApp获取的initData字符串";
        
        // 验证哈希是否合法
        boolean isValid = TelegramWebAppUtils.validateWebAppData(botToken, initData);
        System.out.println("验证结果:" + isValid);
    }
}

这个方法会自动处理密钥生成、HMAC计算等步骤,完全避免手动实现可能出现的编码或字节处理错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:42:55