发布于 2026-01-06 1 阅读
0

使用 Web Crypto API 生成公钥/私钥对,用于 Web 端到端非对称加密 DEV 的全球展示与分享挑战赛,由 Mux 呈现:展示你的项目!

使用 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