crypto/webcrypto 模块 的作用
crypto/webcrypto
模块是 Node.js 提供的一种 Web Cryptography API 的实现,它允许开发者以与浏览器类似的方式在 Node.js 中进行加密操作。它支持对称加密、非对称加密、哈希、数字签名等常见加密任务,适用于需要与浏览器兼容的加密需求,尤其是在跨平台开发中具有很大的便利性。
兼容性与浏览器差异
- 兼容性:
webcrypto
模块的设计目的是为了与浏览器中的window.crypto.subtle
API 兼容,因此 Web 开发者可以在 Node.js 和浏览器中使用相同的 API 进行加密操作。 - 限制:由于某些加密算法或模式可能不在所有平台或环境中得到支持,开发者需要考虑到与浏览器的差异和环境限制。
crypto/webcrypto 模块相关api
1、crypto/webcrypto
模块概述
crypto/webcrypto
模块在 Node.js 版本 15 及更高版本中作为实验性功能提供,并且在版本 16 中开始稳定。这个模块模仿了浏览器环境中的 crypto.subtle
API,提供了加密、解密、哈希计算、签名验证等常见加密操作。
在 Node.js 中,crypto/webcrypto
模块是 Web Cryptography API 的实现,能够让开发者使用与浏览器类似的方式处理加密任务。
1、 加密与解密
Web Cryptography API 提供了多种加密方法,包括对称加密(如 AES)和非对称加密(如 RSA)。
1.1、对称加密(如 AES)
对称加密使用相同的密钥进行加密和解密操作。AES-GCM
是一种常用的对称加密模式。
generateKey(algorithm, extractable, keyUsages)
:生成加密密钥,algorithm
指定算法(例如'AES-GCM'
),extractable
表示密钥是否可以导出,keyUsages
表示密钥的用途(如encrypt
和decrypt
)。encrypt(algorithm, key, data)
:加密数据,algorithm
包含加密算法和 IV 信息,key
是加密密钥,data
是待加密的数据。decrypt(algorithm, key, data)
:解密数据。
示例:使用 AES-GCM 加密与解密
const { webcrypto } = require('crypto');
const { subtle } = webcrypto;
async function encryptDecrypt() {
// 生成密钥
const key = await subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
// 生成随机初始化向量
const iv = webcrypto.getRandomValues(new Uint8Array(12)); // AES-GCM 推荐使用 12 字节长度的 IV
// 明文
const data = new TextEncoder().encode('Hello, World!');
// 加密
const encrypted = await subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
key,
data
);
console.log('Encrypted:', new Uint8Array(encrypted));
// 解密
const decrypted = await subtle.decrypt(
{ name: 'AES-GCM', iv: iv },
key,
encrypted
);
console.log('Decrypted:', new TextDecoder().decode(decrypted));
}
encryptDecrypt();
1.2、非对称加密(如 RSA)
Web Crypto API 还支持非对称加密操作,如 RSA 加密和签名。
generateKey(algorithm, extractable, keyUsages)
:生成非对称密钥对,algorithm
包含加密参数(例如'RSA-OAEP'
)。encrypt(algorithm, key, data)
:使用公钥进行加密。decrypt(algorithm, key, data)
:使用私钥进行解密。
示例:使用 RSA 加密和解密
async function rsaEncryptDecrypt() {
// 生成 RSA 密钥对
const { publicKey, privateKey } = await subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]), // 0x010001
hash: { name: 'SHA-256' }
},
true, // 密钥可导出
['encrypt', 'decrypt']
);
// 明文
const data = new TextEncoder().encode('Hello, RSA!');
// 公钥加密
const encrypted = await subtle.encrypt(
{ name: 'RSA-OAEP' },
publicKey,
data
);
console.log('Encrypted:', new Uint8Array(encrypted));
// 私钥解密
const decrypted = await subtle.decrypt(
{ name: 'RSA-OAEP' },
privateKey,
encrypted
);
console.log('Decrypted:', new TextDecoder().decode(decrypted));
}
rsaEncryptDecrypt();
2、哈希函数
Web Crypto API 提供了多种哈希算法,如 SHA-256、SHA-384、SHA-512 等。
digest(algorithm, data)
:计算数据的哈希,algorithm
是哈希算法(如'SHA-256'
),data
是待哈希的输入数据。
示例:使用 SHA-256 哈希
async function hashData() {
const data = new TextEncoder().encode('Hello, WebCrypto!');
const hash = await subtle.digest('SHA-256', data);
console.log('SHA-256 Hash:', new Uint8Array(hash));
}
hashData();
3、数字签名
Web Crypto API 支持使用私钥对数据进行签名,并且使用公钥进行验证
sign(algorithm, privateKey, data)
:使用私钥生成签名。verify(algorithm, publicKey, signature, data)
:使用公钥验证签名。
示例:生成签名并验证
async function signVerify() {
// 生成 RSA 密钥对
const { publicKey, privateKey } = await subtle.generateKey(
{
name: 'RSA-PSS',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: 'SHA-256' }
},
true, // 密钥可导出
['sign', 'verify']
);
// 数据
const data = new TextEncoder().encode('Hello, sign me!');
// 使用私钥签名
const signature = await subtle.sign(
{ name: 'RSA-PSS', saltLength: 32 },
privateKey,
data
);
console.log('Signature:', new Uint8Array(signature));
// 使用公钥验证签名
const isValid = await subtle.verify(
{ name: 'RSA-PSS', saltLength: 32 },
publicKey,
signature,
data
);
console.log('Signature valid:', isValid);
}
signVerify();
4、密钥导入与导出
Web Crypto API 允许导入和导出加密密钥。
exportKey(format, key)
:导出密钥,format
可以是'jwk'
、'raw'
或'pkcs8'
等。importKey(format, keyData, algorithm, extractable, keyUsages)
:从导出的密钥数据导入密钥。
示例:导入和导出密钥
async function importExportKey() {
// 生成一个 AES 密钥
const key = await subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
// 导出密钥
const exportedKey = await subtle.exportKey('jwk', key);
console.log('Exported Key:', exportedKey);
// 从导出的 JWK 导入密钥
const importedKey = await subtle.importKey(
'jwk',
exportedKey,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
console.log('Imported Key:', importedKey);
}
importExportKey();