如何在JavaScript中对字节数组计算与Python hashlib.sha256兼容的SHA256哈希
问题原因
你得到错误哈希结果的核心原因是CryptoJS.SHA256方法不支持直接传入JavaScript原生数值数组作为输入,它会默认将传入的数组转为字符串(比如将[86, 104, 114, ...]转为"86,104,114,..."格式的字符串后再计算哈希),因此最终结果和Python侧不一致。
兼容解决方案
方案1:修改CryptoJS的调用方式
将原生字节数组转换为CryptoJS支持的WordArray类型后再计算哈希,即可得到和Python侧一致的结果:
const a = "56687282f0f3c1ca76132c6c2fee44ee93a0b3251740719ea3e33b8366d86615"; const bytes = []; for (let c = 0; c < a.length; c += 2) { bytes.push(parseInt(a.substr(c, 2), 16)); } // 原生字节数组转CryptoJS WordArray const wordArray = CryptoJS.lib.WordArray.create(bytes); // 计算哈希,输出十六进制结果 const hash = CryptoJS.SHA256(wordArray).toString(CryptoJS.enc.Hex); // 输出:d7928286f70bf6f89802d9b13bed2aae9c65609133dcd37ae03345b4ee2e8731
方案2:使用原生API(无需引入第三方库)
Node.js环境
直接使用内置的crypto模块:
const crypto = require('crypto'); const a = "56687282f0f3c1ca76132c6c2fee44ee93a0b3251740719ea3e33b8366d86615"; // 直接将hex字符串转为Buffer,不需要手动遍历转换 const buffer = Buffer.from(a, 'hex'); const hash = crypto.createHash('sha256').update(buffer).digest('hex');
浏览器环境
使用原生Web Crypto API:
const a = "56687282f0f3c1ca76132c6c2fee44ee93a0b3251740719ea3e33b8366d86615"; // hex字符串转Uint8Array const bytes = new Uint8Array(a.length / 2); for (let c = 0; c < a.length; c += 2) { bytes[c / 2] = parseInt(a.substr(c, 2), 16); } // 异步计算哈希 crypto.subtle.digest('SHA-256', bytes).then(digestBuffer => { const hash = Array.from(new Uint8Array(digestBuffer)) .map(b => b.toString(16).padStart(2, '0')) .join(''); console.log(hash); });
以上所有方案的输出结果都和Python侧hashlib.sha256(unhexlify(a)).hexdigest()的结果完全一致。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

