Migrating from Node.js crypto to Web Crypto API: A guided experience
Deep into the transition experience of crypto to Web Crypto API, providing a comprehensive guide focusing on 3 commonly scenarios.
Introduction
The Web Crypto API is a new Javascript tool for cryptography. It is compatible with modern browsers and leading platforms, including Cloudflare Workers and Vercel, and also Node.js. Such interoperability implies a developer's dream - write your cryptography code once and run it across numerous platforms using the Web Crypto API.
However, Node.js already has a "crypto" module with a long history, leaving a significant amount of legacy code in need of migration. In this article, we will delve into the transition experience, providing a comprehensive guide focusing on 3 common scenarios. We aim to illuminate the pathway to successful migration.
What is Web Crypto API
Web Crypto API, an open standard by W3C for JavaScript, is a collection of standardised cryptography primitives defined in the Web Cryptography API specification. It was created after several browsers and platforms began adding their own non-interoperable cryptography functions.
The API provides primitives for key generation, encryption and decryption, digital signatures, key and bit derivation, and cryptographic digest. It is centered around an interface called SubtleCrypto, you can find more details and tutorials in the Mozilla MDN documentation.
But Node.js already has crypto module?
Node.js developers are typically familiar with the crypto module. It offers a comprehensive set of cryptographic primitives. This module not only provides mechanisms for the same cryptographic operations defined in the Web Crypto API but often includes a broader range of cryptographic algorithms.
So why do we still need Web Crypto API? As Javascript becomes popular across many platforms and environments , from the client-side to servers and especially on the edge, it's important to have a cross-platform cryptographic tool to simplify processes.
In addition, the functions in Web Crypto API standard all return promises and support the async/await syntax. This is a significant advantage over the crypto module, which is synchronous and can block the event loop.
And there is a interesting thing that Node.js adds its support for Web Crypto API, that means, in most cases, Web Crypto API is perfect in most known platforms.
Using Web Crypto API
On most platforms, the collection of Web Crypto APIs is accessible via the global crypto
object, which includes 3 top-level utilities: getRandomValues
, randomUUID
and subtle
.
There are many differences compared to the traditional crypto module. They can be summarized into 3 most common parts. Let’s go through them and see how to migrate from existing code.
#1 Generate random values
In crypto module, you can generate random values by calling randomBytes
There is a simalar function called getRandomValues
in Web Crypto, but the return value is an ArrayBuffer
, so we need an another step to convert it to string.
#2 Hashing (or digest)
createHash
is easy to use in crypto module:
In Web Crypto, we can use subtle.createHash
As you can see, the transformation from ArrayBuffer
to hex string is also needed.
#3 Encryption and decryption
In crypto module, AES encryption and decryption can be implemented with:
In Web Crypto, we need to create key by importKey
first:
Conclusion
As you can see, the migration is not hard, the main job is to change the syntax to fit the new API and resolve ArrayBuffer
with TextEncoder
.
As an identity product, Logto uses cryptography in many places. We have migrated from the crypto module to the Web Crypto API. This transition enables us to better adapt to edge environments and makes it possible to execute SDK code securely in the browser.