nodejs -- crypto
Node.js 的 crypto 模块是一个内置模块,提供了加密、解密、哈希生成、数字签名和密钥交换等功能。它允许开发者实现许多安全相关的任务,如加密数据、生成哈希值、验证数据完整性等。crypto 模块基于 OpenSSL 库构建,因此提供了丰富的加密算法和功能。
1. 引入 crypto 模块
在使用 crypto 模块之前,需要将它引入:
const crypto = require('crypto');
2. 哈希(Hashing)
哈希是一种单向操作,它将数据映射为一个固定长度的值。crypto 模块提供了多种常见的哈希算法,如 MD5、SHA-1、SHA-256 等。
创建哈希对象
使用 crypto.createHash() 方法可以创建一个哈希对象。
const hash = crypto.createHash('sha256'); // 创建 SHA-256 哈希对象
hash.update('hello world'); // 更新数据
const result = hash.digest('hex'); // 获取哈希结果,'hex' 表示输出为十六进制字符串
console.log(result); // 输出:b94d27b9934d3e08a52e52d7da7dabfa3f5a4f58c8e71c5e080a34c5b760c5e1
1.createHash(algorithm):创建一个哈希对象,常见的算法包括 sha256、sha512、md5 等。
2.update(data):向哈希对象添加数据。可以多次调用该方法,数据会被追加。
3.digest(encoding):计算最终的哈希值,返回一个缓冲区(Buffer)或以指定编码的字符串(如 'hex'、'base64'、'latin1' 等)。
3. HMAC(Hash-based Message Authentication Code)
HMAC 是基于哈希函数和密钥的消息认证码,用于验证数据的完整性和真实性。
创建 HMAC 对象
const hmac = crypto.createHmac('sha256', 'secret-key');
hmac.update('hello world');
const result = hmac.digest('hex');
console.log(result); // 输出:b94d27b9934d3e08a52e52d7da7dabfa3f5a4f58c8e71c5e080a34c5b760c5e1
- createHmac(algorithm, key):创建一个 HMAC 对象,第一个参数是哈希算法,第二个参数是密钥。
- update(data):向 HMAC 对象添加数据。
- digest(encoding):计算最终的 HMAC 值。
4. 加密与解密
crypto 模块支持多种加密算法,如对称加密(AES)和非对称加密(RSA)。加密过程包括加密(encrypt)和解密(decrypt)。
对称加密(对称密钥加密)
对称加密使用相同的密钥进行加密和解密。
加密:
const algorithm = 'aes-256-cbc'; // 加密算法
const key = crypto.randomBytes(32); // 生成一个 256 位的密钥
const iv = crypto.randomBytes(16); // 生成一个初始化向量(IV)
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('Hello, world!', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log('Encrypted:', encrypted);
解密:
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log('Decrypted:', decrypted); // 输出:Hello, world!
- createCipheriv(algorithm, key, iv):创建加密器,algorithm 为加密算法,key 为密钥,iv 为初始化向量。
- createDecipheriv(algorithm, key, iv):创建解密器,参数与加密器相同。
- update(data, inputEncoding, outputEncoding):用于加密或解密数据,inputEncoding 和 outputEncoding 控制数据的编码方式。
- final(encoding):结束加密或解密过程并返回最终结果。
非对称加密(公钥加密和私钥解密)
非对称加密使用公钥加密数据,私钥解密数据。常见的非对称加密算法包括 RSA。
生成密钥对:
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});
console.log('Public Key:', publicKey);
console.log('Private Key:', privateKey);
11.generateKeyPairSync(type, options):生成密钥对(例如 RSA 公钥和私钥)。type 为密钥类型(如 rsa),options 用于指定密钥的大小、编码方式等。
公钥加密:
const encryptedData = crypto.publicEncrypt(publicKey, Buffer.from('Hello, world!'));
console.log('Encrypted:', encryptedData.toString('base64'));
私钥解密:
const decryptedData = crypto.privateDecrypt(privateKey, encryptedData);
console.log('Decrypted:', decryptedData.toString());
5. 数字签名
数字签名用于验证数据的完整性和来源,通常使用私钥签名,公钥验证签名。
创建签名:
const sign = crypto.createSign('SHA256');
sign.update('Hello, world!');
const signature = sign.sign(privateKey, 'base64');
console.log('Signature:', signature);
- createSign(algorithm):创建签名对象,指定哈希算法。
- update(data):向签名对象添加数据。
- sign(privateKey, encoding):使用私钥生成签名,encoding 可以是 'base64'、'hex' 或 'binary'。
验证签名:
const verify = crypto.createVerify('SHA256');
verify.update('Hello, world!');
const isVerified = verify.verify(publicKey, signature, 'base64');
console.log('Verified:', isVerified); // 输出:true 或 false
- createVerify(algorithm):创建验证对象,指定哈希算法。
- verify(publicKey, signature, encoding):验证签名是否有效,publicKey 是公钥,signature 是签名,encoding 是签名的编码格式。
6. 密钥派生
密钥派生是根据某个初始值(如密码)生成加密所需的密钥。
使用 PBKDF2 生成密钥:
const password = 'password123';
const salt = crypto.randomBytes(16); // 随机盐值
crypto.pbkdf2(password, salt, 100000, 64, 'sha512', (err, derivedKey) => {
if (err) throw err;
console.log('Derived Key:', derivedKey.toString('hex'));
});
- pbkdf2(password, salt, iterations, keylen, digest, callback):使用 PBKDF2 算法生成密钥,password 是密码,salt 是盐值,iterations 是迭代次数,keylen 是生成的密钥长度,digest 是哈希算法。
7. 随机数和随机字节
crypto 模块还提供了生成随机数和随机字节的功能,这对于密码学应用中生成密钥、初始化向量等非常重要。
生成随机字节:
const randomBytes = crypto.randomBytes(16); // 生成 16 字节的随机数据
console.log(randomBytes.toString('hex'));
18.randomBytes(size):生成指定大小的随机字节。
生成随机整数:
const randomInt = crypto.randomInt(0, 100); // 生成 0 到 100 之间的随机整数
console.log(randomInt);
- randomInt(min, max):生成一个范围在 min 到 max 之间的随机整数。