SubtleCrypto与Linux sha256sum哈希结果不一致及文件哈希报错问题
问题1:Linux终端sha256sum与Web crypto.subtle计算SHA-256结果不一致
终端操作及结果
$ echo "foobar" | sha256sum aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f -
Web端代码及结果
crypto.subtle.digest("SHA-256", new TextEncoder().encode("foobar")).then((hash) => { console.log("rohdas hash " + hash); let arr = [...new Uint8Array(hash)].map(c => c.toString(16).padStart(2, '0')).join(''); console.log(arr); }).catch(err => console.log(err)); // 输出:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
原因与解决
终端的echo命令默认会在字符串末尾添加换行符,实际计算的是"foobar\n"的哈希值;而Web端代码计算的是纯"foobar"的哈希。只需给echo加-n参数去掉换行符,两边结果就会一致:
$ echo -n "foobar" | sha256sum c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 -
问题2:计算Zip文件SHA-256时的XRayWrapper警告与错误
相关代码
let reader = new FileReader(); reader.readAsArrayBuffer(new File('/data/myfile.zip')); reader.onloadend = () => { console.log(reader.result + " " + reader.result.byteLength); // 输出:[object ArrayBuffer] 336 window.crypto.subtle.digest('SHA-256', reader.result).then((calculatedHash) => { // 触发警告1 console.log("calculatedHash " + calculatedHash); // 输出:calculatedHash [object Opaque] let calculatedHashHex = [...new Uint8Array(calculatedHash)]; // 触发错误2 }).catch((err) => {console.log("digest error " + err);}); }
警告信息
JavaScript Warning: "XrayWrapper denied access to property Symbol.toPrimitive (reason: object is not safely Xrayable). Note that only the first denied property access from a given global object will be reported."
错误信息
JavaScript Error: "Error: Accessing TypedArray data over Xrays is slow, and forbidden in order to encourage performant code. To copy TypedArrays across origin boundaries, consider using Components.utils.cloneInto()."
解决方法
该问题出现在跨源/特权上下文(如浏览器扩展)中,需用cloneInto将哈希对象克隆到当前上下文后再处理:
let reader = new FileReader(); // 注意:浏览器中不能直接用路径创建File,需通过文件选择器获取 document.getElementById('fileInput').addEventListener('change', (e) => { const file = e.target.files[0]; reader.readAsArrayBuffer(file); reader.onloadend = () => { window.crypto.subtle.digest('SHA-256', reader.result).then((calculatedHash) => { // 克隆哈希对象到当前全局上下文 const clonedHash = Components.utils.cloneInto(calculatedHash, window); let calculatedHashHex = [...new Uint8Array(clonedHash)] .map(c => c.toString(16).padStart(2, '0')) .join(''); console.log(calculatedHashHex); }).catch((err) => {console.log("digest error " + err);}); }; });
内容的提问来源于stack exchange,提问作者Rohit Das
相关产品推荐
相关产品推荐

