Node.js 中的 Web Crypto API
模块提供了现代的密码学功能,允许开发者使用加密、解密、签名、验证、哈希等功能。该模块基于 Web Cryptography API 标准,因此提供的 API 与浏览器环境中的类似,具有一致的使用体验。
在 Node.js 中,你可以通过 crypto.webcrypto
来访问 Web Crypto API
。使用示例如下:
const { webcrypto } = require('crypto');
Node.js 的 Web Crypto API
模块包括以下几个主要部分:
SubtleCrypto
CryptoKey
Key Algorithm
Supported Algorithms
getRandomValues
)Web Crypto API
的实际使用示例SubtleCrypto
SubtleCrypto
对象是 Web Crypto API
的核心部分,提供了加密、解密、签名、验证、哈希、密钥生成和导入/导出的功能。
可以通过 crypto.webcrypto.subtle
来访问:
const subtle = webcrypto.subtle;
encrypt()
: 使用指定的加密算法对数据进行加密。decrypt()
: 使用指定的加密算法对密文进行解密。sign()
: 使用密钥对数据进行签名。verify()
: 验证签名的有效性。digest()
: 计算数据的哈希值。generateKey()
: 生成加密密钥。deriveKey()
: 从基础密钥派生新的密钥。deriveBits()
: 从基础密钥派生位数据。importKey()
: 导入现有密钥材料,生成 CryptoKey
对象。exportKey()
: 导出密钥材料。wrapKey()
: 使用密钥对另一个密钥进行加密。unwrapKey()
: 解密加密的密钥。CryptoKey
CryptoKey
对象代表了在 Web Crypto API
中使用的密钥。所有加密操作都依赖于这些密钥对象。CryptoKey
可以是对称密钥或非对称密钥对的组成部分(如 RSA 密钥对中的公钥或私钥)。
CryptoKey
的常用属性:type
: 指示密钥是对称密钥 (secret
) 还是非对称密钥对中的公钥 (public
) 或私钥 (private
)。extractable
: 指示密钥是否可以导出。algorithm
: 密钥的算法。usages
: 密钥的用途,可以是 encrypt
, decrypt
, sign
, verify
, deriveKey
, deriveBits
, wrapKey
, unwrapKey
等。// 生成 AES-GCM 对称密钥
subtle.generateKey(
{
name: "AES-GCM",
length: 256,
},
true, // 密钥是否可导出
["encrypt", "decrypt"]
).then(key => {
console.log(key);
});
KeyAlgorithm
对象定义了 CryptoKey
使用的加密算法,具体包括以下几种:
Optimal Asymmetric Encryption Padding
的非对称加密算法。Probabilistic Signature Scheme
的非对称签名算法。不同算法有各自的参数设置,具体取决于算法的类型。
Node.js Web Crypto API
支持的主要算法如下:
对称加密算法:
AES-GCM
AES-CBC
AES-CTR
AES-KW
(密钥包裹算法)非对称加密算法:
RSA-OAEP
RSA-PSS
(签名验证)密钥协商算法:
ECDH
哈希算法:
SHA-1
SHA-256
SHA-384
SHA-512
消息认证码:
HMAC
getRandomValues()
getRandomValues()
是一种用于生成随机数的安全方法。它可以生成加密强度的随机数,适用于生成密钥材料或其他密码学相关的数据。
const array = new Uint8Array(16);
webcrypto.getRandomValues(array);
console.log(array);
在此示例中,getRandomValues
会生成一个长度为 16 的随机字节数组。
以下是如何使用 AES-GCM
对称加密算法来加密和解密数据的示例:
async function encryptData(data, key) {
const iv = webcrypto.getRandomValues(new Uint8Array(12)); // 初始化向量
const encrypted = await subtle.encrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
data
);
return { encrypted, iv };
}
async function decryptData(encrypted, key, iv) {
const decrypted = await subtle.decrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
encrypted
);
return decrypted;
}
(async () => {
const key = await subtle.generateKey(
{
name: "AES-GCM",
length: 256,
},
true,
["encrypt", "decrypt"]
);
const data = new TextEncoder().encode("Hello World");
const { encrypted, iv } = await encryptData(data, key);
const decrypted = await decryptData(encrypted, key, iv);
console.log(new TextDecoder().decode(decrypted));
})();
下面是使用 SHA-256
算法对数据进行哈希的示例:
async function hashData(data) {
const hash = await subtle.digest("SHA-256", data);
return hash;
}
(async () => {
const data = new TextEncoder().encode("Hello World");
const hash = await hashData(data);
console.log(Buffer.from(hash).toString('hex'));
})();
async function generateKeyPair() {
return await subtle.generateKey(
{
name: "ECDSA",
namedCurve: "P-256", // 可选 "P-384", "P-521"
},
true,
["sign", "verify"]
);
}
async function signData(data, privateKey) {
return await subtle.sign(
{
name: "ECDSA",
hash: "SHA-256",
},
privateKey,
data
);
}
async function verifySignature(data, signature, publicKey) {
return await subtle.verify(
{
name: "ECDSA",
hash: "SHA-256",
},
publicKey,
signature,
data
);
}
(async () => {
const { publicKey, privateKey } = await generateKeyPair();
const data = new TextEncoder().encode("Hello World");
const signature = await signData(data, privateKey);
const isValid = await verifySignature(data, signature, publicKey);
console.log("Signature valid:", isValid);
})();
Node.js 的 Web Crypto API
模块提供了强大的现代密码学支持,包括对称加密、非对称加密、哈希、签名验证、密钥派生等功能。通过 SubtleCrypto
API,开发者能够实现安全的数据加密、解密、哈希和签名功能,同时保持与浏览器端 API 的一致性。这为构建安全应用程序和实现跨平台的密码学操作提供了便捷的解决方案。