客户端 JavaScript 中的哈希计算 (Chrome/V8)

Hash calculation in JavaScript on a client (Chrome/V8)

在 Node.js 中,我可以借助 crypto 模块计算哈希值:

import crypto from "crypto";

const myHash = await crypto.createHash("SHA3-512").update("myText", "utf8").digest("base64");

由于 Node.js 基于 V8,我认为此代码应该适用于任何支持 V8 的浏览器(Chrome、Edge、Opera 等)。但是好像不是这样的

根据 Web Crypto API,crypto.subtle.digest 不支持开箱即用的 SHA3-512,要获得正确的哈希字符串,我需要进行 digest() 结果 (ArrayBuffer) 手动,例如:

const buf = await crypto.subtle.digest("SHA-512", new TextEncoder("utf-8").encode("myText"));

const myHash = Array.prototype.map.call(new Uint8Array(buf), arrItem => (("00" + arrItem.toString(16)).slice(-2))).join("");

这种 «API-不一致» 非常令人惊讶,是否有任何替代方案,允许将 Node.js crypto 模块 API-经验带到 V8-强大的客户端?

crypto模块未被V8实现;它由相应的嵌入器 (Chrome/Node/...) 提供。这意味着没有技术原因会迫使所有嵌入器提供相同的 API。 (从好的方面来说,这也意味着客户端是建立在 V8 还是其他 JS 引擎上无关紧要——所有现代浏览器都支持相同的 Web Crypto API。)我不知道为什么 Node 选择来了使用他们自己的 API,可能是因为它比 Web Crypto API?

存在的时间更长

看起来 Node 15.0 添加了 Web Crypto API 的实现:https://nodejs.org/api/webcrypto.html。所以你可以使用它来让你的代码在服务器和客户端上工作。

作为替代方案,您可以编写一个小垫片来抽象化差异。或者您可以查找现有的软件包;例如快速搜索 https://www.npmjs.com/package/crypto-browserify(没有个人经验,所以没有特别认可)。

无论采用何种方法,在浏览器中,您都只能使用 Web Crypto API 支持的算法,目前包括 SHA-512 但不包括 SHA3-512。