加密与哈希
在Node.js开发中,加密与哈希是保障数据安全的核心技术。两者虽常被混淆,但分别用于不同场景:加密可逆,用于保护敏感信息传输;哈希不可逆,常用于密码存储和数据完整性校验。
加密技术基础
Node.js通过crypto
模块提供加密功能,支持对称加密(如AES)和非对称加密(如RSA)。对称加密使用相同密钥加解密,适合大数据量处理;非对称加密则使用公钥/私钥对,更安全但性能较低。
AES加密示例:
const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
function encrypt(text) {
let cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
console.log(encrypt('秘密数据')); // 输出加密结果
哈希函数应用
哈希函数将任意长度数据映射为固定长度值,具有单向性。Node.js中常用SHA-256、MD5(不推荐)等算法,主要用于密码存储和文件校验。
密码加盐哈希示例:
const crypto = require('crypto');
function hashPassword(password, salt) {
return crypto.pbkdf2Sync(
password,
salt,
100000,
64,
'sha512'
).toString('hex');
}
const salt = crypto.randomBytes(32).toString('hex');
console.log(hashPassword('user123', salt)); // 存储哈希值与盐
密钥派生函数
PBKDF2、scrypt等算法专门用于从密码派生密钥,通过增加计算复杂度防范暴力破解。Node.js的crypto.scrypt
实现内存密集型计算,更抗ASIC攻击。
scrypt示例:
crypto.scrypt('password', 'salt', 64, { N: 16384 }, (err, derivedKey) => {
console.log(derivedKey.toString('hex'));
});
消息认证码
HMAC结合哈希与密钥,用于验证消息完整性和真实性。常见于API签名验证场景。
HMAC-SHA256实现:
const hmac = crypto.createHmac('sha256', 'secret-key');
hmac.update('待验证数据');
console.log(hmac.digest('hex'));
性能与安全权衡
加密操作消耗CPU资源,在Web服务器中需注意:
- 同步API会阻塞事件循环
- 调整PBKDF2迭代次数需平衡安全与性能
- 使用
crypto.createCipheriv
而非已废弃的createCipher
异步加密示例:
crypto.pbkdf2('password', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
if (err) throw err;
console.log(derivedKey.toString('hex'));
});
实际应用场景
- HTTPS通信:TLS协议混合使用对称/非对称加密
- JWT令牌:HMAC或RSA签名验证令牌有效性
- 数据库加密:字段级加密保护用户隐私数据
- 区块链:哈希链确保数据不可篡改
JWT签名验证片段:
const jwt = require('jsonwebtoken');
const token = jwt.sign({ user: 'admin' }, 'hmac-secret', { algorithm: 'HS256' });
jwt.verify(token, 'hmac-secret', (err, decoded) => {
console.log(decoded); // { user: 'admin' }
});
常见漏洞防范
- 弱哈希算法:避免使用MD5/SHA-1,优先选择SHA-256/512
- 盐值重复:每个密码使用独立随机盐
- ECB模式:AES应使用CBC或GCM等更安全模式
- 密钥管理:禁止硬编码密钥,使用环境变量或密钥管理系统
安全随机数生成:
// 不安全
Math.random().toString(36).substring(2);
// 安全方式
crypto.randomBytes(32).toString('hex');
Node.js版本差异
不同Node版本加密支持存在差异:
- v10.0.0起
pbkdf2
默认迭代次数从1000增至100000 - v15.0.0废弃
createCipher
/createDecipher
- v17.0.0增加Web Crypto API的有限实现
版本兼容写法:
const { createCipheriv, createDecipheriv } = crypto;
// 替代已废弃的createCipher
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn