简体中文
  • 加密
  • 边缘

从 Node.js crypto 迁移到 Web Crypto API:引导式经验

深入了解从 crypto 迁移到 Web Crypto API 的过渡经验,提供着重于 3 个常见场景的全面指南。

Sijie
Sijie
Developer

引言

Web Crypto API 是一个用于加密的新 Javascript 工具。它与现代浏览器和主要平台,包括 Cloudflare WorkersVercel,以及 Node.js 兼容。这样的互操作性意味着开发者的梦想 - 用 Web Crypto API 编写一次你的加密代码,并在众多平台上运行。

然而,Node.js 已经有一个带有长久历史的 "crypto" 模块,留下了大量需要迁移的遗留代码。在这篇文章中,我们将深入了解过渡经验,提供着重于 3 个常见场景的全面指南。我们的目标是照亮成功迁移的道路。

什么是 Web Crypto API

Web Crypto API 是一个 W3C 为 JavaScript 开放的标准,是 Web Cryptography API 规范 中定义的一系列标准化加密原语的集合。它是在一些浏览器和平台开始添加他们自己的不可互操作加密函数后创建的。

该 API 为密钥生成、加密和解密、数字签名、密钥和位派生、加密摘要提供了原语。它以一个名为 SubtleCrypto 的接口为中心,你可以在 Mozilla MDN 文档中找到更多详细信息和教程。

但是 Node.js 已经有 crypto 模块了吗?

Node.js 开发者通常熟悉 crypto 模块。它提供了一套全面的加密原语。这个模块不仅为 Web Crypto API 中定义的相同加密操作提供了机制,而且通常还包括更广泛的加密算法。

那么我们为什么还需要 Web Crypto API 呢?随着 Javascript 变得在许多平台和环境中流行,从客户端到服务器,特别是在边缘,拥有一个跨平台的加密工具以简化流程是很重要的。

另外,Web Crypto API 标准中的函数都返回 promise 并支持异步 / 等待语法。这是它相对于同步的、可能会阻塞事件循环的 crypto 模块的一个显著优势。

还有一个有趣的事情是 Node.js 增加了 对 Web Crypto API 的支持,这意味着,在大多数情况下,Web Crypto API 在大多数已知平台上都是完美的。

使用 Web Crypto API

在大多数平台上,Web Crypto API 的集合可以通过全局 crypto 对象访问,其中包括 3 个顶级工具:getRandomValuesrandomUUIDsubtle

与传统的 crypto 模块相比,有很多不同。他们可以总结成 3 个最常见的部分。让我们一起来看看如何从现有代码迁移。

#1 生成随机值

在 crypto 模块中,你可以通过调用 randomBytes 生成随机值

在 Web Crypto 中有一个类似的函数叫 getRandomValues,但是返回值是一个 ArrayBuffer,所以我们需要另一个步骤将它转换成字符串。

#2 哈希(或摘要)

createHash 在 crypto 模块中易于使用:

在 Web Crypto 中,我们可以使用 subtle.createHash

如你所见,从 ArrayBuffer 转换为十六进制字符串也是必需的。

#3 加密和解密

在 crypto 模块中,可以用以下方式实现 AES 加密和解密:

在 Web Crypto 中,我们需要首先通过 importKey 创建密钥:

结论

如你所见,迁移并不难,主要工作是改变语法以适应新的 API 并用 TextEncoder 解决 ArrayBuffer

作为一个身份产品,Logto 在许多地方使用了加密。我们已经从 crypto 模块迁移到了 Web Crypto API。这种转变使我们能够更好地适应边缘环境,并使在浏览器中安全地执行 SDK 代码成为可能。