使用 Web Crypto API 生成用于 Web 端到端非对称加密的公钥/私钥对
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
首先声明,我并非密码学专家——我只是一个对密码学,尤其是非对称密码学感兴趣的开发者。这些概念非常深奥,我只能浅尝辄止,但我们不妨先来浅尝辄止一下吧?
公钥接下来怎么办?
公钥密码学(或者如果你喜欢,也可以叫它非对称密码学)是密码学中的一个概念,大约一年前它引起了我的兴趣,因为乍一看它似乎毫无道理,但却又非常实用。它的基本思想是,你可以创建一组加密密钥,这些密钥协同工作,其中一个密钥可以加密数据,而只有另一个密钥才能解密这些数据。
这听起来可能令人困惑,但这正是我们日常使用的许多加密技术(ssh、ssl 等以 . 开头的缩写s)的核心所在,而且理由充分:我们需要能够在不受信任的环境中共享秘密。
我想直接看代码,所以如果你需要更多关于公钥密码学的解释,我推荐你观看Computerphile 制作的这个很棒的视频。
进入window.crypto.subtle
既然我们已经解决了“是什么”的问题,接下来让我们看看“如何做”,这涉及到使用Web Crypto API。
生成密钥对其实非常简单crypto.subtle.generateKey——难点在于如何设置参数。我打算使用 RSA-OAEP 算法,并采用推荐的模数长度4096和公钥指数65437(需要用 UInt8Array 表示),SHA-256哈希算法也采用推荐的哈希算法。
现在我们已经确定了这些变量,只需要将它们代入generateKey方法中即可:
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
上面的代码会返回一个 Promise,该 Promise 会解析为一个CryptoKeyPair类似这样的对象{publicKey: CryptoKey, privateKey: CryptoKey。很简单。
接下来怎么办?
就是这样,但其实也没什么用。首先,对象CryptoKey中包含的元素CryptoKeyPair只能在你当前所在的页面上生效。所以,依我看,它们目前基本上只适合用于演示目的。
接下来我们需要做的就是能够导出它们,以便它们可以重复使用。依我之见,最方便的方法是将它们导出为 JSON Web Keys,因为 Web Crypto API 开箱即用地支持这种格式:
const publicKey = await crypto.subtle.exportKey("jwk", keyPair.publicKey);
const privateKey = await crypto.subtle.exportKey("jwk", keyPair.privateKey);
现在我们已经将密钥对导出为 JWK 格式,可以将私钥保存在安全的地方,例如,还可以发布公钥,允许通过不可信的方式向我们发送只有我们才能解密的加密消息。不过,我们以后再讨论这个问题。
文章来源:https://dev.to/jrgould/use-the-web-crypto-api-to-generate-a-public-private-key-pair-for-end-to-end-asymmetry-cryptography-on-the-web-2mpe