Node.js crypto 模块全面入门
一、模块概述
Node.js 的 crypto
模块是内置的核心模块,基于 OpenSSL 库构建,提供加密、解密、哈希、签名等安全功能。它封装了 OpenSSL 的哈希、HMAC、加密、解密、签名和验证方法,适用于数据加密、安全传输、身份验证等场景。
二、核心功能详解
1. 哈希与 HMAC
1.1 哈希(Hash)
- 定义:将任意长度数据映射为固定长度的摘要,单向不可逆。
- 常用算法:SHA-256、SHA-512、MD5(不推荐,已不安全)。
- 代码示例:
const crypto = require('crypto'); const hash = crypto.createHash('sha256'); hash.update('Hello World'); const digest = hash.digest('hex'); console.log(digest); // 输出哈希值
1.2 HMAC(基于哈希的消息认证码)
- 定义:结合密钥和哈希算法,验证数据完整性和真实性。
- 代码示例:
const crypto = require('crypto'); const hmac = crypto.createHmac('sha256', 'secret-key'); hmac.update('Hello World'); const result = hmac.digest('hex'); console.log(result); // 输出HMAC值
2. 对称加密
2.1 AES 加密(推荐 AES-256-GCM)
- 算法:AES(高级加密标准),常用模式包括 CBC、GCM(支持认证)。
- 步骤:
- 生成密钥和 IV(初始化向量)。
- 使用
createCipheriv
加密,createDecipheriv
解密。
- 代码示例(AES-256-GCM):
const crypto = require('crypto'); const algorithm = 'aes-256-gcm'; const key = crypto.randomBytes(32); // 256位密钥 const iv = crypto.randomBytes(12); // GCM模式IV为12字节// 加密 const cipher = crypto.createCipheriv(algorithm, key, iv); let encrypted = cipher.update('Hello World', 'utf8', 'hex'); encrypted += cipher.final('hex'); const tag = cipher.getAuthTag(); // 认证标签// 解密 const decipher = crypto.createDecipheriv(algorithm, key, iv); decipher.setAuthTag(tag); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8');
2.2 注意事项
- IV 管理:每次加密使用不同的随机 IV,并与密文一起存储。
- 编码:确保加密和解密时使用相同的编码(如
hex
、base64
)。
3. 非对称加密(RSA)
3.1 密钥对生成
- 代码示例:
const crypto = require('crypto'); const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {modulusLength: 2048,publicKeyEncoding: { type: 'spki', format: 'pem' },privateKeyEncoding: { type: 'pkcs8', format: 'pem' } });
3.2 加密与解密
- 公钥加密,私钥解密:
const encryptedData = crypto.publicEncrypt(publicKey, Buffer.from('Hello World')); const decryptedData = crypto.privateDecrypt(privateKey, encryptedData);
4. 数字签名与验证
4.1 签名生成(私钥签名)
- 代码示例:
const crypto = require('crypto'); const sign = crypto.createSign('SHA256'); sign.update('Hello World'); const signature = sign.sign(privateKey, 'hex');
4.2 签名验证(公钥验证)
- 代码示例:
const verify = crypto.createVerify('SHA256'); verify.update('Hello World'); const isValid = verify.verify(publicKey, signature, 'hex');
三、安全最佳实践
- 密钥管理:
- 使用
crypto.randomBytes
生成高熵密钥。 - 密钥存储在环境变量或专用密钥管理系统(如 AWS KMS)。
- 使用
- 算法选择:
- 避免 MD5、SHA1 等弱算法,优先使用 SHA-256、AES-256。
- 对称加密推荐 AES-256-GCM(支持认证)。
- 初始化向量(IV):
- 每次加密生成随机 IV,并与密文一起存储。
- 编码一致性:
- 确保加密、解密时使用相同的输入/输出编码(如
utf8
转hex
)。
- 确保加密、解密时使用相同的输入/输出编码(如
四、高级主题
1. 分组加密模式
- 常见模式:
- CBC(密码分组链接):需要 IV,安全性较高。
- GCM(伽罗瓦计数器模式):支持认证,推荐用于现代应用。
- 填充方案:
- PKCS7 填充(默认),确保数据块长度符合要求。
2. 文件加解密
- 流程:
- 读取文件内容。
- 使用对称加密算法加密/解密。
- 存储 IV、认证标签(如 GCM)与密文。
- 代码示例(文件签名):
const fs = require('fs'); const crypto = require('crypto');// 生成签名 const privateKey = fs.readFileSync('privatekey.pem', 'utf8'); const data = fs.readFileSync('file.txt'); const sign = crypto.createSign('RSA-SHA256'); sign.write(data); sign.end(); const signature = sign.sign(privateKey, 'hex');// 验证签名 const publicKey = fs.readFileSync('publickey.pem', 'utf8'); const verify = crypto.createVerify('RSA-SHA256'); verify.write(data); verify.end(); const isValid = verify.verify(publicKey, signature, 'hex');
3. 性能优化
- 流式处理:
- 使用
update()
方法分块处理大文件,避免内存溢出。
- 使用
- 硬件加速:
- 通过
crypto.setEngine
启用 OpenSSL 引擎(如 Intel SGX)。
- 通过
五、常见问题与解决方案
- 编码错误:
- 确保加密和解密时使用相同的编码格式(如
hex
、base64
)。
- 确保加密和解密时使用相同的编码格式(如
- 密钥长度不匹配:
- AES-256 需要 32 字节密钥,RSA 推荐 2048 位或更高。
- IV 重复使用:
- 每次加密生成新的随机 IV,并与密文一起存储。
六、总结
Node.js 的 crypto
模块提供了全面的加密功能,涵盖哈希、对称/非对称加密、签名等场景。通过合理选择算法、管理密钥和遵循安全实践,可有效保障数据安全。对于复杂需求,可结合流式处理和硬件加速优化性能。