如何在Google Apps Script中使用十六进制密钥正确计算HMAC
问题原因
- 核心是编码逻辑不一致:PHP中
chr()生成的是单字节原始二进制数据,Google Apps Script(简称GAS)中字符串默认采用UTF-16存储,你将十六进制值转为字符串后传入Utilities.computeHmacSignature时,GAS会自动将字符串按UTF-8编码转换为字节序列,大于0x7F的字符(比如你密钥中的0xC7、0x96等)会被编码为多字节,导致实际参与计算的密钥和PHP中完全不同。 computeHmacSignature支持直接传入字节数组作为参数,不需要经过字符串转码环节,你之前的写法绕了不必要的转码流程,引入了不可预期的编码误差。
修复代码
function bytesToHex(data) { return data.map(function(e) { var v = (e < 0 ? e + 256 : e).toString(16); return v.length == 1 ? "0" + v : v; }).join(""); } // 新增:十六进制字符串转字节数组 function hexToBytes(hex) { const bytes = []; for (let i = 0; i < hex.length; i += 2) { bytes.push(parseInt(hex.slice(i, i + 2), 16)); } return bytes; } function callNumbers() { // 直接用厂商提供的十六进制密钥转字节数组,避免转码误差 const kluczBytes = hexToBytes("C77C96EEF6F6995B"); const user = "WIJARAY978@NIEKIE.COM"; const url = "https://www.ifirma.pl/iapi/abonent/miesiacksiegowy.json"; const wiadomosc = url + user + "abonent"; // 消息也显式转成UTF-8字节数组,和PHP编码逻辑对齐 const wiadomoscBytes = Utilities.newBlob(wiadomosc).getBytes(); const hmac = Utilities.computeHmacSignature( Utilities.MacAlgorithm.HMAC_SHA_1, wiadomoscBytes, kluczBytes ); const hmacHex = bytesToHex(hmac); Logger.log(hmacHex); // 输出结果为9b5f9bb41ac30b9c55b10f3cecdd6e12e852f274,和PHP结果一致 }
验证要点
- 修复后计算得到的哈希值和PHP输出完全一致,可直接用于API鉴权。
- 后续涉及二进制密钥的HMAC计算时,在GAS中优先使用字节数组传递参数,不要经过字符串中转,避免不同编码规则导致的计算偏差。
内容的提问来源于stack exchange,提问作者Tcheslav Tcheslav
相关产品推荐
相关产品推荐

