在前端开发中,加密和解密是一个重要的部分。在 Node.js 中,crypto 模块提供了一系列的加密和解密方法,包括对称加密、非对称加密以及哈希算法等。本文将详细介绍 Node.js 中的 crypto 模块,包括其常用方法、使用示例以及注意事项。
常用方法
对称加密
对称加密是指加密和解密使用同一个密钥的加密方式。Node.js 中的 crypto 模块提供了多种对称加密算法,包括 AES、DES、3DES 等。其中,AES 是最常用的对称加密算法之一。
AES 加密
AES 加密使用的是一个密钥和一个初始化向量(IV),其中密钥是用于加密和解密的秘密密钥,而 IV 则是用于加密过程中的初始值。下面是一个简单的 AES 加密示例:
// www.javascriptcn.com code example
const crypto = require('crypto');
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update('Hello, world!', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log('Encrypted:', encrypted);在上面的示例中,我们首先生成了一个 32 字节的密钥和一个 16 字节的 IV,然后使用 crypto.createCipheriv() 方法创建了一个 AES 加密器,指定了加密算法为 aes-256-cbc,使用了生成的密钥和 IV,最后使用 cipher.update() 方法对明文进行加密,并使用 cipher.final() 方法输出加密后的密文。
AES 解密
AES 解密使用的密钥和 IV 必须与加密时使用的相同。下面是一个简单的 AES 解密示例:
// www.javascriptcn.com code example
const crypto = require('crypto');
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update('Hello, world!', 'utf8', 'hex');
encrypted += cipher.final('hex');
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log('Decrypted:', decrypted);在上面的示例中,我们首先生成了一个 32 字节的密钥和一个 16 字节的 IV,然后使用 crypto.createCipheriv() 方法创建了一个 AES 加密器,指定了加密算法为 aes-256-cbc,使用了生成的密钥和 IV,最后使用 cipher.update() 方法对明文进行加密,并使用 cipher.final() 方法输出加密后的密文。接着,我们使用 crypto.createDecipheriv() 方法创建了一个 AES 解密器,使用了相同的密钥和 IV,最后使用 decipher.update() 方法对密文进行解密,并使用 decipher.final() 方法输出解密后的明文。
非对称加密
非对称加密是指加密和解密使用不同密钥的加密方式。Node.js 中的 crypto 模块提供了多种非对称加密算法,包括 RSA、DSA 等。其中,RSA 是最常用的非对称加密算法之一。
RSA 加密
RSA 加密使用的是一对公私钥,其中公钥用于加密,私钥用于解密。下面是一个简单的 RSA 加密示例:
// www.javascriptcn.com code example
const crypto = require('crypto');
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
const message = 'Hello, world!';
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(message, 'utf8')).toString('base64');
console.log('Encrypted:', encrypted);在上面的示例中,我们首先使用 crypto.generateKeyPairSync() 方法生成了一对公私钥,指定了加密算法为 RSA,密钥长度为 2048 位。接着,我们定义了一个明文字符串 message,使用 crypto.publicEncrypt() 方法对其进行加密,并将结果转换为 Base64 编码的字符串输出。
RSA 解密
RSA 解密使用的是一对公私钥,其中公钥用于加密,私钥用于解密。下面是一个简单的 RSA 解密示例:
// www.javascriptcn.com code example
const crypto = require('crypto');
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
const message = 'Hello, world!';
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(message, 'utf8')).toString('base64');
const decrypted = crypto.privateDecrypt(privateKey, Buffer.from(encrypted, 'base64')).toString('utf8');
console.log('Decrypted:', decrypted);在上面的示例中,我们首先使用 crypto.generateKeyPairSync() 方法生成了一对公私钥,指定了加密算法为 RSA,密钥长度为 2048 位。接着,我们定义了一个明文字符串 message,使用 crypto.publicEncrypt() 方法对其进行加密,并将结果转换为 Base64 编码的字符串。最后,我们使用 crypto.privateDecrypt() 方法对密文进行解密,并将结果转换为 UTF-8 编码的字符串输出。
哈希算法
哈希算法是指将任意长度的输入(也称为消息)压缩成固定长度的输出(也称为哈希值)的算法。Node.js 中的 crypto 模块提供了多种哈希算法,包括 SHA-1、SHA-256、SHA-512 等。
SHA-256 哈希
SHA-256 是一种常用的哈希算法,其输出长度为 256 位。下面是一个简单的 SHA-256 哈希示例:
const crypto = require('crypto');
const message = 'Hello, world!';
const hash = crypto.createHash('sha256').update(message).digest('hex');
console.log('Hash:', hash);在上面的示例中,我们定义了一个明文字符串 message,使用 crypto.createHash() 方法创建了一个 SHA-256 哈希器,并使用 hash.update() 方法将明文字符串输入哈希器,最后使用 hash.digest() 方法输出哈希值,以十六进制字符串的形式表示。
使用示例
加密和解密
下面是一个使用 AES 对称加密算法进行加密和解密的示例:
// www.javascriptcn.com code example
const crypto = require('crypto');
const key = '0123456789abcdef0123456789abcdef';
const iv = '0123456789abcdef';
function encrypt(plaintext) {
const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
function decrypt(ciphertext) {
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
let decrypted = decipher.update(ciphertext, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const plaintext = 'Hello, world!';
const ciphertext = encrypt(plaintext);
const decrypted = decrypt(ciphertext);
console.log('Plaintext:', plaintext);
console.log('Ciphertext:', ciphertext);
console.log('Decrypted:', decrypted);在上面的示例中,我们首先定义了一个 16 字节的密钥和一个 16 字节的 IV。接着,我们定义了两个函数 encrypt() 和 decrypt(),分别用于对明文进行加密和对密文进行解密。其中,crypto.createCipheriv() 方法用于创建一个 AES 加密器,指定了加密算法为 aes-128-cbc,使用了定义的密钥和 IV;crypto.createDecipheriv() 方法用于创建一个 AES 解密器,使用了相同的密钥和 IV。最后,我们定义了一个明文字符串 plaintext,使用 encrypt() 函数对其进行加密,并将结果输出;接着,我们使用 decrypt() 函数对密文进行解密,并将结果输出。
哈希
下面是一个使用 SHA-256 哈希算法对字符串进行哈希的示例:
// www.javascriptcn.com code example
const crypto = require('crypto');
function hash(message) {
return crypto.createHash('sha256').update(message).digest('hex');
}
const message = 'Hello, world!';
const hashed = hash(message);
console.log('Message:', message);
console.log('Hashed:', hashed);在上面的示例中,我们定义了一个 hash() 函数,用于对输入字符串进行 SHA-256 哈希,并将结果输出。其中,crypto.createHash() 方法用于创建一个 SHA-256 哈希器,使用了 hash.update() 方法将输入字符串输入哈希器,最后使用 hash.digest() 方法输出哈希值,以十六进制字符串的形式表示。最后,我们定义了一个明文字符串 message,使用 hash() 函数对其进行哈希,并将结果输出。
注意事项
在使用 crypto 模块进行加密和解密时,需要注意以下事项:
- 密钥和 IV 的生成应使用随机数生成器,以增加安全性。
- 在使用对称加密算法时,密钥和 IV 必须与加密时使用的相同。
- 在使用非对称加密算法时,应将私钥保存在安全的地方,以免泄露。
- 在使用哈希算法时,哈希值不可逆,应谨慎使用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d1d9f5a941bf71343c9c5c