從 Node.js crypto 遷移到 Web Crypto API:引導式體驗
深入探討從 crypto 過渡到 Web Crypto API 的經驗,提供著重於三種常見情境的全面指南。
介紹
Web Crypto API 是一個新的 Javascript 加密工具。它兼容現代瀏覽器和領先的平台,包括 Cloudflare Workers 和 Vercel,以及 Node.js。這種互操作性意味著開發者的夢想——只需編寫一次你的加密代碼,就可以在多個平台上使用 Web Crypto API 運行。
然而,Node.js 已經有一個歷史悠久的 "crypto" 模組,留下大量需要遷移的遺留代碼。在本文中,我們將深入探討遷移經驗,提供著重於三種常見情境的全面指南。我們的目標是照亮成功遷移的道路。
甚麼是 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 並支持 async/await 語法。這是其對比 crypto 模組的顯著優勢,因為後者是同步的,可能會阻塞事件循環。
還有一個有趣的是,Node.js 添加了對 Web Crypto API 的支持,這意味著在大多數情況下,Web Crypto API 在大多數已知平台中都完美適用。
使用 Web Crypto API
在大多數平台上,Web Crypto APIs 的集合可以通過全局的 crypto
對象訪問,其中包括三個頂級實用工具:getRandomValues
、randomUUID
和 subtle
。
與傳統的 crypto 模組相比,有很多不同之處。它們可以總結為最常見的三個部分。我們看看它們,然後看看如何從現有代碼中遷移。
#1 生成隨機值
在 crypto 模組中,你可以通過調用 randomBytes
生成隨機值:
在 Web Crypto 中有一個類似的功能叫做 getRandomValues
,但返回值是一個 ArrayBuffer
,因此我們需要另一個步驟將其轉換為字符串。
#2 散列(或摘要)
在 crypto 模組中使用 createHash
很簡單:
在 Web Crypto 中,我們可以使用 subtle.createHash
如你所見,ArrayBuffer
到十六進制字符串的轉換也是需要的。
#3 加密和解密
在 crypto 模組中,AES 加密和解密可以實現如下:
在 Web Crypto 中,我們需要首先通過 importKey
創建密鑰:
結論
如你所見,遷移並不困難,主要任務是改變語法以適應新 API 並使用 TextEncoder
處理 ArrayBuffer
。
作為一個身份產品,Logto 在許多地方使用了加密技術。我們已經從 crypto 模組遷移到 Web Crypto API。這一轉變使我們能夠更好地適應邊緣環境,並使得可以在瀏覽器中安全執行 SDK 代碼。