Java转JavaScript实现HMAC计算结果不一致问题咨询
解决Java转JavaScript HMAC-SHA1哈希不一致的问题
我来帮你排查下问题所在,你现在哈希值不匹配主要是JavaScript代码对密钥和数据的处理逻辑和Java端完全不符,具体问题点和修复方案如下:
问题分析
- 密钥处理错误:Java端直接使用原始字节数组
signKey = {20,54,50,82}作为HMAC的密钥材料,但你在JavaScript里错误地用了new Buffer(signKey, 'base64')——这相当于把密钥数组当成base64字符串去解码,完全偏离了Java的逻辑。 - 语法错误导致数据异常:JavaScript里的
time = 0,0,0,0,0,8,21,60是无效的数组写法,这会导致new Buffer(time)处理出错误的字节数据,和Java端的time字节数组完全不对应。
修复后的JavaScript代码
const crypto = require('crypto'); // 修正数组语法,和Java端保持一致的字节数组 const time = [0, 0, 0, 0, 0, 8, 21, 60]; const signKey = [20, 54, 50, 82]; // 直接将字节数组转为Buffer,无需base64解码,和Java逻辑对齐 const hash = crypto .createHmac('sha1', Buffer.from(signKey)) .update(Buffer.from(time)) .digest('hex'); console.log(`hash ${hash}`);
对应完整的Java验证代码
为了方便你对比,我把你没写完的Java代码补全,确保两边逻辑完全一致:
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.HexFormat; public class HmacSha1Test { public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException { byte[] time = {0, 0, 0, 0, 0, 8, 21, 60}; byte[] signKey = {20, 54, 50, 82}; SecretKeySpec secretKey = new SecretKeySpec(signKey, "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(secretKey); byte[] hashBytes = mac.doFinal(time); // 转换为十六进制字符串,和JS的digest('hex')输出格式一致 String hash = HexFormat.of().formatHex(hashBytes); System.out.println("hash " + hash); } }
现在两边运行后生成的哈希值就会完全一致了——核心就是保证密钥和待加密数据的字节序列在两端完全相同,避免不必要的编码转换(比如错误的base64解码)。
内容的提问来源于stack exchange,提问作者rafazzevedo
相关产品推荐
相关产品推荐

