Node.js 中的密码学:使用 crypto 进行加密和哈希

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

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 和密码学文章,请访问我们的网站。

推荐