Node.js 中的密码学:内置模块 crypto
在现代 Web 开发中,数据安全是一个至关重要的方面。Node.js 提供了一个强大且灵活的内置模块 crypto,它实现了广泛的密码学功能。该模块无需安装额外的包,即可解决哈希、对称和非对称加密、创建数字签名和 HMAC(基于哈希的消息认证码)等任务。
在本文中,我们将详细解析 crypto 的主要功能,并提供实用的代码示例。
crypto 模块的主要功能
- 哈希 — 将任意长度的数据转换为固定长度的字符串(SHA-256、SHA-512、MD5)。
- 对称加密 — 使用单个密钥进行加密和解密(AES-256-CBC、AES-192-GCM)。
- 非对称加密 — 使用密钥对(公钥/私钥)进行加密,基于 RSA 或 ECDH。
- HMAC — 使用密钥进行哈希,以验证消息的完整性和真实性。
- 数字签名 — 创建和验证签名以确认作者身份。
导入模块
crypto 模块内置于 Node.js 中,因此可以通过标准方式导入:
const crypto = require('crypto');示例 1:数据哈希(SHA-256)
哈希是一种单向函数,常用于存储密码和验证文件完整性。
const data = 'PythonLib — 教育门户';
// 创建 SHA-256 哈希const hash = crypto.createHash('sha256');hash.update(data);const hexHash = hash.digest('hex');
console.log('原始数据:', data);console.log('SHA-256 哈希:', hexHash);// 输出:SHA-256 哈希: b5a1... (64 个字符)重要提示: 存储密码时,不要使用简单哈希,而应使用带“盐”的函数——例如 crypto.scryptSync() 或 pbkdf2Sync()。
示例 2:带盐的密码哈希(scrypt)
const password = 'MySecurePassword123';
// 生成随机盐const salt = crypto.randomBytes(16).toString('hex');
// 使用盐创建哈希(scrypt)const hash = crypto.scryptSync(password, salt, 64).toString('hex');
console.log('盐:', salt);console.log('密码哈希:', hash);
// 验证时使用相同的盐并比较哈希const isMatch = crypto.scryptSync(password, salt, 64).toString('hex') === hash;console.log('密码匹配:', isMatch); // true示例 3:对称加密 AES-256-CBC
对称加密使用同一个密钥进行加密和解密。AES-256-CBC 算法还需要初始化向量(IV)。
// 加密函数function encrypt(text, key) { const iv = crypto.randomBytes(16); // 生成 IV const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { iv: iv.toString('hex'), encrypted };}
// 解密函数function decrypt(encrypted, key, ivHex) { const iv = Buffer.from(ivHex, 'hex'); const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted;}
// 使用示例const key = crypto.randomBytes(32); // 256 位密钥const secretMessage = 'PythonLib 的机密数据';
const encryptedData = encrypt(secretMessage, key);console.log('加密后:', encryptedData.encrypted);console.log('IV:', encryptedData.iv);
const decryptedMessage = decrypt(encryptedData.encrypted, key, encryptedData.iv);console.log('解密后:', decryptedMessage); // PythonLib 的机密数据示例 4:HMAC(基于哈希的消息认证码)
HMAC 使用密钥对消息进行哈希,以确保消息在传输过程中未被篡改。
const message = 'PythonLib 的重要消息';const secretKey = 'my-secret-key';
// 创建 HMACconst hmac = crypto.createHmac('sha256', secretKey);hmac.update(message);const hmacHex = hmac.digest('hex');
console.log('HMAC:', hmacHex);
// 验证 HMAC(接收方使用相同的密钥和消息重新计算)const expectedHmac = crypto.createHmac('sha256', secretKey).update(message).digest('hex');console.log('HMAC 匹配:', hmacHex === expectedHmac); // true示例 5:数字签名(RSA)
数字签名使用非对称加密来验证消息的真实性和完整性。首先需要生成 RSA 密钥对。
const { generateKeyPairSync, sign, verify } = require('crypto');
// 生成 RSA 密钥对const { publicKey, privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' }});
const document = 'PythonLib 的文档';
// 创建签名const signature = sign('sha256', Buffer.from(document), { key: privateKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING});
console.log('签名:', signature.toString('base64'));
// 验证签名const isVerified = verify('sha256', Buffer.from(document), { key: publicKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING}, signature);
console.log('签名有效:', isVerified); // true结论
Node.js 的 crypto 模块是一个强大的工具,用于实现现代 Web 应用程序中的各种密码学任务。从简单的哈希到复杂的数字签名,该模块提供了所有必要的功能,无需第三方库。但是,请记住:密码学是一个复杂的领域,在生产中使用时,请始终遵循最佳实践并关注安全更新。
更多关于 PythonLib 教育门户的 Node.js 和密码学文章,请访问我们的网站。