Node.js crypto 模块
Node.js 的 crypto
模块是一个内置模块,提供了加密功能,包括对 OpenSSL 的哈希、HMAC、加密、解密、签名和验证功能的封装。它允许开发者在 Node.js 应用程序中执行各种加密操作。
核心功能
哈希算法
哈希算法是将任意长度的输入转换为固定长度输出的单向函数。crypto
模块支持多种哈希算法,如 SHA-256、MD5 等。
实例
const crypto = require('crypto');
// 创建 SHA-256 哈希
const hash = crypto.createHash('sha256');
hash.update('Hello World');
console.log(hash.digest('hex'));
// 输出: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146
// 创建 SHA-256 哈希
const hash = crypto.createHash('sha256');
hash.update('Hello World');
console.log(hash.digest('hex'));
// 输出: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146
HMAC (密钥哈希消息认证码)
HMAC 是一种使用加密哈希函数结合密钥的消息认证机制。
实例
const crypto = require('crypto');
const secret = 'mysecret';
const hmac = crypto.createHmac('sha256', secret);
hmac.update('Hello World');
console.log(hmac.digest('hex'));
// 输出: 9b8e8b0e3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a
const secret = 'mysecret';
const hmac = crypto.createHmac('sha256', secret);
hmac.update('Hello World');
console.log(hmac.digest('hex'));
// 输出: 9b8e8b0e3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a
加密与解密
对称加密
对称加密使用相同的密钥进行加密和解密。crypto
模块支持 AES、DES 等算法。
实例
const crypto = require('crypto');
// 加密
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('Hello World', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// 解密
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// 加密
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('Hello World', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// 解密
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
非对称加密
非对称加密使用公钥和私钥对,公钥用于加密,私钥用于解密。
实例
const crypto = require('crypto');
// 生成密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 加密
const encryptedData = crypto.publicEncrypt(
publicKey,
Buffer.from('Hello World')
);
console.log(encryptedData.toString('base64'));
// 解密
const decryptedData = crypto.privateDecrypt(
privateKey,
encryptedData
);
console.log(decryptedData.toString());
// 生成密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 加密
const encryptedData = crypto.publicEncrypt(
publicKey,
Buffer.from('Hello World')
);
console.log(encryptedData.toString('base64'));
// 解密
const decryptedData = crypto.privateDecrypt(
privateKey,
encryptedData
);
console.log(decryptedData.toString());
数字签名与验证
数字签名用于验证数据的完整性和来源。
实例
const crypto = require('crypto');
// 生成密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 创建签名
const sign = crypto.createSign('SHA256');
sign.update('some data to sign');
const signature = sign.sign(privateKey, 'hex');
console.log(signature);
// 验证签名
const verify = crypto.createVerify('SHA256');
verify.update('some data to sign');
console.log(verify.verify(publicKey, signature, 'hex'));
// 输出: true
// 生成密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 创建签名
const sign = crypto.createSign('SHA256');
sign.update('some data to sign');
const signature = sign.sign(privateKey, 'hex');
console.log(signature);
// 验证签名
const verify = crypto.createVerify('SHA256');
verify.update('some data to sign');
console.log(verify.verify(publicKey, signature, 'hex'));
// 输出: true
随机数生成
crypto
模块提供了生成密码学安全随机数的方法。
实例
const crypto = require('crypto');
// 生成 16 字节的随机数
const randomBytes = crypto.randomBytes(16);
console.log(randomBytes.toString('hex'));
// 生成随机整数
const randomInt = crypto.randomInt(1, 100);
console.log(randomInt);
// 生成 16 字节的随机数
const randomBytes = crypto.randomBytes(16);
console.log(randomBytes.toString('hex'));
// 生成随机整数
const randomInt = crypto.randomInt(1, 100);
console.log(randomInt);
安全注意事项
- 密钥管理:永远不要将密钥硬编码在代码中,使用环境变量或密钥管理系统。
- 算法选择:避免使用已知不安全的算法如 MD5、SHA1。
- **初始化向量(IV)**:对于对称加密,每次加密都应使用不同的 IV。
- 密码学参数:使用足够长的密钥长度(如 AES-256 而不是 AES-128)。
实际应用场景
- 密码存储:使用哈希算法存储用户密码
- 数据传输加密:保护网络传输中的数据
- API 签名验证:确保 API 请求的完整性
- JWT 令牌:生成和验证 JSON Web Tokens
- 文件完整性检查:验证下载文件的哈希值
总结
Node.js 的 crypto
模块提供了强大的加密功能,是构建安全应用程序的重要工具。通过合理使用哈希、加密、签名等功能,开发者可以有效保护数据安全。在使用时,务必遵循安全最佳实践,选择合适的算法和参数。
对于更复杂的安全需求,可以考虑使用专门的加密库如 bcrypt
、argon2
等,它们针对特定用途进行了优化。
点我分享笔记