node之crypto模块,Node环境加密

2023-12-13 06:10:56
一、简介

crypto 是 Node.js 内置的加密模块,提供了一组用于加密、解密、签名、验证和生成随机数的功能。它支持多种加密算法和哈希算法,可以用于保护数据的机密性和完整性。
以下是 crypto 模块提供的一些常用功能:

  1. 对称加密:crypto 模块提供了对称加密算法,如 AES、DES、3DES 等。使用相同的密钥进行加密和解密,适用于对称加密场景。
  2. 非对称加密:crypto 模块支持非对称加密算法,如 RSA、DSA、ECC 等。非对称加密使用一对密钥,公钥用于加密数据,私钥用于解密数据或生成数字签名。
  3. 哈希算法:crypto 模块提供了多种哈希算法,如 MD5、SHA-1、SHA-256 等。哈希算法可将任意长度的数据转换为固定长度的哈希值,常用于数据完整性校验和密码存储。
  4. 数字签名:crypto 模块支持使用私钥生成数字签名,并使用公钥验证签名的有效性。数字签名用于确保数据的完整性和身份验证。
    5.随机数生成:crypto 模块提供了生成随机数的功能,可用于生成安全的密钥和初始化向量等。
二、哈希算法
  1. hash = crypto.createHash(algorithm,options):创建哈希算法对象,algorithm:哈希算法名称,md5、sha1、sha224、sha256、sha384、sha512、blake2b、blake2s、sha3_224、sha3_256、sha3_384、sha3_512、hake_128、shake_256
const crypto = require('crypto');

const data = 'Hello, World!';

const hash = crypto.createHash('md5');
hash.update(data);
const hashValue = hash.digest('hex');

console.log('加密数据:', data);
console.log('MD5 Hash:', hashValue);
  1. crypto.getHashes():获取支持的哈希算法列表
  2. hash.copy(options):返回哈希对象的副本。options 参数是一个对象,用于指定要进行复制的选项。这个方法可以用于在复制哈希对象的状态之后继续计算哈希值,而不影响原始哈希对象。
  3. hash.end(chunk,encoding,cb):用于结束哈希计算并返回最终的哈希值
  • chunk:要进行加密的最后一个数据块。可以是一个 Buffer、TypedArray 或一个字符串。如果提供了 chunk,则会在加密操作之前将其加密并返回最后一部分加密数据。如果不提供 chunk,则该方法仅用于结束加密操作并返回最后一部分加密数据。
  • encoding输入数据块的编码格式。如果提供了 chunk,则可以使用 encoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果不提供 chunk,则可以忽略该参数。
  • cb:回调函数,在加密操作完成后被调用。回调函数接受两个参数,第一个参数是错误对象(如果有错误),第二个参数是加密后的数据。如果提供了回调函数,则加密操作完成后将调用该函数;否则,加密操作完成后将返回一个 Buffer 对象,其中包含加密后的数据。
  1. hash.digest(encoding):返回计算的哈希值。encoding 参数是一个可选参数,用于指定返回的哈希值的编码格式,默认为二进制。常见的编码格式包括 ‘hex’(十六进制)、‘base64’(Base64 编码)等。
  2. hash.map(fn):用于在计算哈希值之前对输入数据进行转换。它接受一个函数 fn,该函数将被应用于输入数据。map() 方法返回一个新的哈希对象,可以继续使用该对象进行哈希计算。
  3. hash.update(data,inputEncoding):用于向哈希对象添加要计算哈希值的数据。可以多次调用 update() 方法以追加数据。通常,在调用 digest() 之前,需要使用 update() 添加所有的数据。
  • data:要进行加密的数据,可以是一个 Buffer、TypedArray 或一个字符串。
  • inputEncoding:输入数据的编码格式。如果 data 是一个字符串,可以使用 inputEncoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果 data 是一个 Buffer 或 TypedArray,则可以忽略该参数。
  • inputEncoding:输入数据的编码格式。如果 data 是一个字符串,可以使用 inputEncoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果 data 是一个 Buffer 或 TypedArray,则可以忽略该参数。
三、HMAC算法
  1. hmac = crypto.createHmac(algorithm,key,option):创建hmac对象
  • algorithm:哈希算法名称,md5、sha1、sha224、sha256、sha384、sha512、blake2b、blake2s、sha3_224、sha3_256、sha3_384、sha3_512、hake_128、shake_256
  • key:HMAC 的密钥,可以是字符串或 Buffer 类型。密钥用于增加哈希的安全性
const crypto = require('crypto');

const data = 'Hello, World!';
const key = 'secretKey';

const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
const digest = hmac.digest('hex');

console.log('原数据:', data);
console.log('加密结果:', digest);

  1. hmac.end(chunk,encoding,cb):用于结束哈希计算并返回最终的哈希值。cb 是一个可选的回调函数,在哈希计算完成后被调用。如果提供了回调函数,那么哈希值将作为回调函数的参数传递。
  • chunk:要进行加密的最后一个数据块。可以是一个 Buffer、TypedArray 或一个字符串。如果提供了 chunk,则会在加密操作之前将其加密并返回最后一部分加密数据。如果不提供 chunk,则该方法仅用于结束加密操作并返回最后一部分加密数据。
  • encoding:输入数据块的编码格式。如果提供了 chunk,则可以使用 encoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果不提供 chunk,则可以忽略该参数。
  • cb:回调函数,在加密操作完成后被调用。回调函数接受两个参数,第一个参数是错误对象(如果有错误),第二个参数是加密后的数据。如果提供了回调函数,则加密操作完成后将调用该函数;否则,加密操作完成后将返回一个 Buffer 对象,其中包含加密后的数据。
  1. hmac.digest(encoding):返回计算的哈希值。encoding 参数是一个可选参数,用于指定返回的哈希值的编码格式,默认为二进制。常见的编码格式包括 ‘hex’(十六进制)、‘base64’(Base64 编码)等。
  2. hmac.map(fn):用于在计算哈希值之前对输入数据进行转换。它接受一个函数 fn,该函数将被应用于输入数据。map() 方法返回一个新的哈希对象,可以继续使用该对象进行哈希计算。
  3. hmac.update(data,inputEncoding):用于向哈希对象添加要计算哈希值的数据。可以多次调用 update() 方法以追加数据。通常,在调用 digest() 之前,需要使用 update() 添加所有的数据。
  • data:要进行加密的数据,可以是一个 Buffer、TypedArray 或一个字符串。
  • inputEncoding:输入数据的编码格式。如果 data 是一个字符串,可以使用 inputEncoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果 data 是一个 Buffer 或 TypedArray,则可以忽略该参数。
四、对称加密算法
  1. cipher = crypto.createDecipheriv(cipher, key, iv):创建加解密对象
  • cipher:表示所使用的加密算法。例如,对于 AES 加密算法,可以使用 ‘aes-256-cbc’
'''
AES:算法名-长度-模式
aes-128-cbc
aes-192-cbc
aes-256-cbc
'''

'''
DES、RC2、RC4:算法名-模式
des-cbc
rc2-cbc
rc4-cbc
'''
  • key:表示加密密钥。这个参数应该是一个字符串、Buffer 或 TypedArray,表示用于加密和解密的密钥。密钥的长度取决于所使用的加密算法。
  • iv:表示初始化向量(Initialization Vector,简称 IV)。这个参数应该是一个字符串、Buffer 或 TypedArray,用于指定加密算法的初始化向量。IV 的长度通常与加密算法的块大小相匹配。
const crypto = require('crypto');

// 加密函数
function encrypt(text, key, iv) {
    const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    return encrypted;
}

// 解密函数
function decrypt(encryptedText, key, iv) {
    const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
    let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

const originalText = 'Hello, World!';
const encryptionKey = crypto.randomBytes(32); // 256 位密钥
const iv = crypto.randomBytes(16); // 128 位初始化向量

const encryptedText = encrypt(originalText, encryptionKey, iv);

const decryptedText = decrypt(encryptedText, encryptionKey, iv);


console.log('原数据:', originalText);
console.log('加密数据:', encryptedText);
console.log('解密数据:', decryptedText);

  1. crypto.getCiphers():获取支持的加密算法列表
  2. crypto.getCipherInfo(cipher):获取加密算法信息
  3. crypto.createSecretKey(key, encoding):创建一个对称加密算法的密钥对象。
  • key:这是一个必需参数,表示用于创建秘密密钥的密钥材料。它可以是一个字符串或一个 Buffer。密钥材料通常是由用户提供或通过其他方式生成。
  • encoding:这是一个可选参数,表示密钥材料的编码方式。它可以是以下字符串之一:
  • ‘hex’:表示密钥材料以十六进制编码的字符串形式提供。
  • ‘base64’:表示密钥材料以 Base64 编码的字符串形式提供。
  • ‘buffer’:表示密钥材料以 Buffer 对象的形式提供。
  1. cipher.final(outputEncoding):返回计算的哈希值。outputEncoding 参数是一个可选参数,用于指定返回的哈希值的编码格式,默认为二进制。常见的编码格式包括 ‘hex’(十六进制)、‘base64’(Base64 编码)等。
  2. cipher.update(data, inputEncoding, outputEncoding):用于向哈希对象添加要计算哈希值的数据。可以多次调用 update() 方法以追加数据。通常,在调用 digest() 之前,需要使用 update() 添加所有的数据
  • data:要进行加密的数据,可以是一个 Buffer、TypedArray 或一个字符串。
  • inputEncoding:输入数据的编码格式。如果 data 是一个字符串,可以使用 inputEncoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果 data 是一个 Buffer 或 TypedArray,则可以忽略该参数。
  • outputEncoding:输出数据的编码格式。加密后的数据可以使用 outputEncoding 参数指定其编码格式,例如 ‘hex’、‘base64’ 等。如果不提供该参数,则返回一个 Buffer 对象。
  1. cipher.end(chunk, encoding, cb):用于结束哈希计算并返回最终的哈希值
  • chunk:要进行加密的最后一个数据块。可以是一个 Buffer、TypedArray 或一个字符串。如果提供了 chunk,则会在加密操作之前将其加密并返回最后一部分加密数据。如果不提供 chunk,则该方法仅用于结束加密操作并返回最后一部分加密数据。
  • encoding:输入数据块的编码格式。如果提供了 chunk,则可以使用 encoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果不提供 chunk,则可以忽略该参数。
  • cb:回调函数,在加密操作完成后被调用。回调函数接受两个参数,第一个参数是错误对象(如果有错误),第二个参数是加密后的数据。如果提供了回调函数,则加密操作完成后将调用该函数;否则,加密操作完成后将返回一个 Buffer 对象,其中包含加密后的数据。
  1. cipher.map(fn):用于在计算哈希值之前对输入数据进行转换。它接受一个函数 fn,该函数将被应用于输入数据。map() 方法返回一个新的哈希对象,可以继续使用该对象进行哈希计算。
五、非对称加密算法
  1. crypto.generateKeyPairSync(type,options):同步生成密钥对,其中包括公钥和私钥
  • type:指定要生成的密钥对的类型,rsa、dsa、ec
  • options:生成密钥时的配置项
'''
RSA 密钥对选项:

modulusLength(可选):指定 RSA 密钥对的模数长度(以位为单位)。默认为 2048。
publicExponent(可选):指定 RSA 公钥的指数。默认为 65537。
privateKeyEncoding(可选):指定私钥的编码格式。可以是 'pem' 或 'der'。默认为 'pem'。
publicKeyEncoding(可选):指定公钥的编码格式。可以是 'pem' 或 'der'。默认为 'pem'。
'''
'''
DSA 密钥对选项:

primeLength(可选):指定 DSA 密钥对的素数长度(以位为单位)。默认为 2048。
privateKeyEncoding(可选):指定私钥的编码格式。可以是 'pem' 或 'der'。默认为 'pem'。
publicKeyEncoding(可选):指定公钥的编码格式。可以是 'pem' 或 'der'。默认为 'pem'。
'''
'''
ECC 密钥对选项:

namedCurve(可选):指定 ECC 密钥对的曲线名称。可以是 'secp256k1'、'secp384r1'、'secp521r1' 等。默认为 'secp256k1'。
privateKeyEncoding(可选):指定私钥的编码格式。可以是 'pem' 或 'der'。默认为 'pem'。
publicKeyEncoding(可选):指定公钥的编码格式。可以是 'pem' 或 'der'。默认为 'pem'。
'''
  1. crypto.generateKeyPair(type,options,callback):生成密钥对,其中包括公钥和私钥
  2. crypto.createPrivateKey(key):创建一个私钥对象。
  3. crypto.createPublicKey(key)):创建一个公钥对象。
  4. crypto.privateDecrypt(privateKey, encryptedData, encoding):
  • privateKey:表示用于解密的私钥。可以是一个 PrivateKeyObject,也可以是一个包含私钥的 PEM 格式字符串或 DER 编码的私钥数据。
  • encryptedData:表示要解密的数据。可以是一个 Buffer 对象或一个字符串。
  • encoding:表示解密后的数据的编码格式。可以是 ‘utf8’、‘hex’ 或 ‘base64’。默认为 ‘utf8’。
  1. crypto.privateEncrypt(privateKey, data, encoding):
  • privateKey:表示用于加密的私钥。可以是一个 PrivateKeyObject,也可以是一个包含私钥的 PEM 格式字符串或 DER 编码的私钥数据。
  • data:表示要加密的数据。可以是一个 Buffer 对象或一个字符串。
  • encoding:表示加密后的数据的编码格式。可以是 ‘utf8’、‘hex’ 或 ‘base64’。默认为 ‘utf8’。
  1. crypto.publicDecrypt(publicKey, encryptedData, encoding):
  • publicKey:表示用于解密的公钥。可以是一个 PublicKeyObject,也可以是一个包含公钥的 PEM 格式字符串或 DER 编码的公钥数据。
  • encryptedData:表示要解密的数据。可以是一个 Buffer 对象或一个字符串。
  • encoding:表示解密后的数据的编码格式。可以是 ‘utf8’、‘hex’ 或 ‘base64’。默认为 ‘utf8’。
  1. crypto.publicEncrypt(publicKey, data, encoding):
  • publicKey:表示用于加密的公钥。可以是一个 PublicKeyObject,也可以是一个包含公钥的 PEM 格式字符串或 DER 编码的公钥数据。
  • data:表示要加密的数据。可以是一个 Buffer 对象或一个字符串。
  • encoding:表示加密后的数据的编码格式。可以是 ‘utf8’、‘hex’ 或 ‘base64’。默认为 ‘utf8’
const crypto = require('crypto');

// 生成 RSA 密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

// 要加密的数据
const plaintext = 'Hello, RSA encryption!';

// 使用公钥进行加密
const encryptedData = crypto.publicEncrypt(publicKey, Buffer.from(plaintext, 'utf8'));

// 将加密后的数据转换为 Base64 编码的字符串
const encryptedText = encryptedData.toString('base64');

// 使用私钥进行解密
const decryptedData = crypto.privateDecrypt(privateKey, encryptedData);

// 将解密后的数据转换为字符串
const decryptedText = decryptedData.toString('utf8');

console.log('原数据:', plaintext);
console.log('加密数据:', encryptedText);
console.log('解密数据:', decryptedText);
六、sign数字签名
  1. sign = crypto.createSign(algorithm, options):创建签名对象
  • algorithm:表示要使用的签名算法。可以是以下之一:
  • ‘RSA-SHA1’、‘RSA-SHA256’、‘RSA-SHA384’、‘RSA-SHA512’:使用 RSA 算法和指定的哈希算法进行签名。
  • ‘DSA-SHA1’、‘DSA-SHA256’:使用 DSA 算法和指定的哈希算法进行签名。
  • ‘ECDSA-SHA1’、‘ECDSA-SHA256’、‘ECDSA-SHA384’、‘ECDSA-SHA512’:使用 ECDSA 算法和指定的哈希算法进行签名。
  • ‘HMAC-SHA1’、‘HMAC-SHA256’、‘HMAC-SHA512’:使用 HMAC 算法和指定的哈希算法进行签名。
  • ‘RSA-MD4’、‘RSA-MD5’、‘RSA-MDC2’、‘RSA-RIPEMD160’:使用 RSA 算法和指定的哈希算法进行签名(不推荐使用)。
  • options(可选):一个可选的对象,用于指定其他选项:
  • key:表示使用的密钥。可以是一个 PrivateKeyObject 或一个包含私钥的 PEM 格式字符串。
  • passphrase:表示密钥的密码(如果有的话)。
  • dhparam:表示 Diffie-Hellman 参数(仅适用于某些算法)。
  • pssSaltLength:表示使用 PSS 签名时的盐长度(仅适用于某些算法)。
const crypto = require('crypto');

// 生成密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

const data = 'Hello, world!';// 要签名的数据
const algorithm = 'RSA-SHA256';

const sign = crypto.createSign(algorithm);// 创建签名对象

sign.update(data);// 更新要签名的数据

const signature = sign.sign(privateKey);// 生成签名

console.log('签名结果:', signature.toString('hex'));

const isValid = crypto.verify(algorithm,data,publicKey,signature)
console.log('验证结果:', isValid);
  1. crypto.verify(algorithm,data,publicKey,signature):验证签名结果
  • algorithm:签名算法名
  • data:原数据
  • publicKey:公钥
  • signature:签名数据
  1. sign.update(data, inputEncoding):该方法用于更新要签名的数据
  • data 参数表示要更新的数据,可以是字符串或 Buffer 对象
  • inputEncoding 是可选的,用于指定 data 的编码方式,默认为 ‘utf8’。
  1. sign.sign(privateKey, outputFormat):该方法用于生成签名
  • privateKey 参数表示要使用的私钥,可以是字符串、Buffer 对象或 KeyObject。
  • outputFormat 是可选的,用于指定生成签名的输出格式,默认为 ‘buffer’。可以使用 ‘hex’、‘base64’ 等格式。
  1. sign.end(chunk, encoding, cb):该方法用于结束签名过程
  • chunk:要进行签名的最后一个数据块。可以是一个 Buffer、TypedArray 或一个字符串。如果提供了 chunk,则会在签名操作之前将其签名并返回最后一部分签名数据。如果不提供 chunk,则该方法仅用于结束签名操作并返回最后一部分签名数据。
  • encoding:输入数据块的编码格式。如果提供了 chunk,则可以使用 encoding 参数指定其编码格式,例如 ‘utf8’、‘hex’ 等。如果不提供 chunk,则可以忽略该参数。
  • cb:回调函数,在签名操作完成后被调用。回调函数接受两个参数,第一个参数是错误对象(如果有错误),第二个参数是签名后的数据。如果提供了回调函数,则签名操作完成后将调用该函数;否则,签名操作完成后将返回一个 Buffer 对象,其中包含签名后的数据。
  1. verify = crypto.createVerify(algorithm):创建验证对象,algorithm 签名算法名称
  2. verify.end(chunk, encoding, cb):在验证数据的最后一块数据块上调用此方法
  • chunk:最后一块数据
  • encoding:可选的数据编码
  • cb:可选的回调函数
  1. verify.update(data, inputEncoding):更新要验证的数据
  • data:要验证的数据
  • inputEncoding:可选的数据编码。
  1. verify.verify(publicKey, signature, signature_format):使用公钥和签名进行验证
  • publicKey:公钥对象,可以是 PEM 格式的字符串、Buffer 或包含 PEM 格式的对象
  • signature :要验证的签名数据
  • signature_format:签名数据的编码格式,例如 ‘base64’ 或 ‘hex’。
七、派生密钥

生密钥是通过使用密钥派生函数从原始密钥或共享密钥生成的新密钥。派生密钥通常用于加密、认证和其他安全目的。

  1. crypto.pbkdf2(password, salt, iterations, keylen, digest, callback):使用 PBKDF2算法派生密钥,适用于HMAC、AES
  • password:一个字符串或 Buffer,表示密码。
  • salt:一个字符串或 Buffer,表示盐值。
  • iterations:一个整数,表示迭代次数,用于增加派生密钥的计算复杂度。
  • keylen:一个整数,表示派生密钥的长度(以字节为单位)。
  • digest:一个字符串,表示用于派生密钥的哈希算法。
  • callback:一个回调函数,用于处理派生密钥。回调函数接受两个参数,第一个参数是错误对象(如果有错误发生),第二个参数是派生的密钥(一个 Buffer 对象)
  1. crypto.pbkdf2Sync(password, salt, iterations, keylen, digesk):同步地使用 PBKDF2 算法派生密钥,适用于HMAC、AES,参数和crypto.pbkdf2相同
const crypto = require('crypto');

// 定义密码和盐值
const password = 'myPassword';
const salt = crypto.randomBytes(16); // 生成一个随机的盐值

// 定义加密算法使用的参数
const iterations = 100000; // 迭代次数
const keyLength = 32; // 生成的密钥长度
const digest = 'sha512'; // 哈希算法

// 生成加密密钥
const key = crypto.pbkdf2Sync(password, salt, iterations, keyLength, digest);

// 加密函数
function encrypt(text, key, iv) {
    const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    return encrypted;
}

// 解密函数
function decrypt(encryptedText, key, iv) {
    const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
    let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

const originalText = 'Hello, World!';
const encryptionKey = crypto.randomBytes(32); // 256 位密钥
const iv = crypto.randomBytes(16); // 128 位初始化向量

const encryptedText = encrypt(originalText, encryptionKey, iv);

const decryptedText = decrypt(encryptedText, encryptionKey, iv);


console.log('原数据:', originalText);
console.log('加密数据:', encryptedText);
console.log('解密数据:', decryptedText);
  1. crypto.hkdf(hash, key, salt, info, length, callback):使用 HKDF算法派生密钥,适用于HMAC、AES
  • hash: 指定所使用的哈希算法。例如,‘sha256’ 或 ‘sha512’。
  • key: 用作 HKDF 的输入密钥。
  • salt: 用作 HKDF 的 salt。salt 可以是任意长度,但长度不能超过 hash 函数的块大小。对于 SHA-256,这个值是 64 字节。
  • info: 用作 HKDF 的 info 参数。它提供了有关密钥的额外信息。
  • length: 指定生成的密钥的长度(以字节为单位)。
  • callback: 当密钥生成完成后会被调用。它接受两个参数:一个错误对象和一个生成的密钥
  1. crypto.hkdfSync(hash, key, salt, info, length):同步地使用 HKDF 算法派生密钥,适用于HMAC、AES,参数和crypto.hkdf相同
const crypto = require('crypto');

// 定义参数
const hash = 'sha256';
const skey = crypto.randomBytes(16); // 输入密钥
const salt = crypto.randomBytes(16); // salt
const info = 'Derived key'; // info 参数
const length = 32; // 生成的密钥长度(字节)

// 使用 crypto.hkdf 生成密钥
const key = crypto.hkdfSync(hash, skey, salt, info, length);

const data = 'Hello, World!';

const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
const digest = hmac.digest('hex');

console.log('原数据:', data);
console.log('加密结果:', digest);

  1. crypto.scrypt(password, salt, keylen, options, callback):使用 scrypt 算法派生密钥,适用于HMAC、AES
  • password: 一个字符串或 Buffer,用作 scrypt 的输入密码。
  • salt: 一个字符串或 Buffer,用作 scrypt 的 salt。salt 的长度通常需要是 16 字节,但也可以是其他长度。
  • keylen: 一个整数,指定生成的密钥的长度(以字节为单位)。
  • options: 一个对象,包含 scrypt 算法的配置选项。可以包含以下属性:
  • N: 内存使用因子,表示在内存中存储的块数。默认值为 16384。
  • r: 在内存中存储的每个块的字节数。默认值为 8。
  • p: 在内存中存储的每个块的概率。默认值为 1。
  • callback: 一个回调函数,当密钥生成完成后会被调用。它接受两个参数:一个错误对象和一个生成的密钥。
    6.crypto.scryptSync(password, salt, keylen, options):同步地使用 scrypt 算法派生密钥,适用于HMAC、AES,参数和crypto.scrypt相同
const crypto = require('crypto');


// 定义参数
const password = 'myPassword';
const salt = crypto.randomBytes(16).toString('hex'); // salt
const keylen = 32; // 生成的密钥长度(字节)
const options = { N: 16384, r: 8, p: 1 }; // scrypt 算法的选项

// 使用 crypto.scrypt 生成密钥
const key = crypto.scryptSync(password, salt, keylen, options);

const data = 'Hello, World!';

const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
const digest = hmac.digest('hex');

console.log('原数据:', data);
console.log('加密结果:', digest);

八、密钥交换协

密钥交换是一种协议或算法,用于在通信参与方之间安全地协商共享密钥。通过密钥交换,通信参与方可以在不安全的通信渠道上建立共享密钥,以用于后续的加密通信。以下是密钥交换的一些主要用途:

  • 保密通信:密钥交换允许通信参与方在不安全的通信渠道上建立共享密钥。这样,他们可以使用共享密钥进行对称加密,确保通信内容的保密性。只有知道共享密钥的参与方才能解密和阅读通信数据。
  • 数据完整性:通过密钥交换,通信参与方可以协商共享密钥,并使用该密钥生成消息认证码(MAC)来保护通信数据的完整性。接收方可以使用相同的密钥和算法验证 MAC,以确保数据在传输过程中没有被篡改。
  • 身份验证:密钥交换可以用于实现身份验证。通信参与方可以使用密钥交换生成的密钥对通信进行数字签名,以证明其身份。其他参与方可以使用签名者的公钥验证签名的有效性,从而确认对方的身份。
  • 密钥派生:密钥交换生成的共享密钥可以用作密钥派生函数(KDF)的输入。通过将共享密钥输入到 KDF 中,可以派生出更多的密钥,用于不同的加密操作,例如对称加密、消息认证码(MAC)生成等。
  1. diffieHellman = crypto.createDiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding):创建一个 Diffie-Hellman 密钥交换对象。
  • sizeOrKey:密钥交换所需的参数。它可以是以下之一:
  • 整数,表示密钥长度(以位为单位)。有效值范围是 2^16 - 1 到 2^512 - 1。
  • 字符串或 Buffer,表示已存在的 Diffie-Hellman 密钥。
  • keyEncoding:密钥材料的编码方式。它可以是以下字符串之一:
  • ‘hex’:表示密钥材料以十六进制编码的字符串形式提供。
  • ‘base64’:表示密钥材料以 Base64 编码的字符串形式提供。
  • ‘buffer’:表示密钥材料以 Buffer 对象的形式提供。
  • generator:生成器的值。它通常是一个整数,范围在 1 到 (2^31 - 1) 之间。如果省略此参数,则默认使用值 2。
  • genEncoding:生成器的编码方式。它可以是以下字符串之一:
  • ‘hex’:表示生成器以十六进制编码的字符串形式提供。
  • ‘base64’:表示生成器以 Base64 编码的字符串形式提供。
  • ‘buffer’:表示生成器以 Buffer 对象的形式提供。
const crypto = require('crypto');


// Diffie-Hellman参数
const generator = crypto.randomBytes(2);
const modulus = crypto.randomBytes(2);

// Alice生成Diffie-Hellman私钥和公钥
const alice = crypto.createDiffieHellman(modulus, generator);
const alicePublicKey = alice.generateKeys('hex');

// Bob生成Diffie-Hellman私钥和公钥
const bob = crypto.createDiffieHellman(modulus, generator);
const bobPublicKey = bob.generateKeys('hex');

// 使用PBKDF2从共享密钥派生更强的密钥
const salt = crypto.randomBytes(16); // 随机生成盐值
const iterations = 100000; // 迭代次数
const derivedKeyLength = 32; // 派生密钥的长

// Alice计算共享密钥的派生值
const aliceSharedSecret = alice.computeSecret(bobPublicKey,'hex');
const aliceDerivedKey = crypto.pbkdf2Sync(aliceSharedSecret, salt, iterations, derivedKeyLength, 'sha256');

// Bob计算共享密钥的派生值
const bobSharedSecret = bob.computeSecret(alicePublicKey,'hex');
const bobDerivedKey = crypto.pbkdf2Sync(bobSharedSecret, salt, iterations, derivedKeyLength, 'sha256');

// 使用HMAC对消息进行认证
const message = 'Hello, Word!';  // 要发送的消息(PDF文件)
const aliceHmac = crypto.createHmac('sha256', aliceDerivedKey);  // 使用派生密钥初始化Alice的HMAC
aliceHmac.update(message);  // 更新Alice的HMAC的输入消息
const aliceDigest = aliceHmac.digest('hex');  // 计算Alice的HMAC摘要并返回十六进制字符串

console.log('Alice的派生密钥:', aliceDerivedKey.toString('hex'));
console.log('Bob的派生密钥:', bobDerivedKey.toString('hex'));
console.log('消息:', message);
console.log('HMAC加密数据:', aliceDigest);

// Bob验证消息的完整性
const bobHmac = crypto.createHmac('sha256', bobDerivedKey);  // 使用派生密钥初始化Bob的HMAC
bobHmac.update(message);  // 更新Bob的HMAC的输入消息
const bobDigest = bobHmac.digest('hex');  // 计算Bob的HMAC摘要并返回十六进制字符串

if (aliceDigest === bobDigest) {  // 比较Bob的HMAC摘要与Alice的HMAC摘要是否相同
  console.log('消息完整性验证通过');
} else {
  console.log('消息完整性验证失败');
}
  1. crypto.diffieHellman(options):创建一个 Diffie-Hellman 密钥交换对象。
  2. diffieHellman =crypto.createDiffieHellmanGroup(name):创建一个 Diffie-Hellman 群组,已内置模数和生成器
const crypto = require('crypto');


// Diffie-Hellman参数
const group = 'modp14'; // Diffie-Hellman群组名称

// Alice生成Diffie-Hellman私钥和公钥
const alice = crypto.createDiffieHellmanGroup(group);
const alicePublicKey = alice.generateKeys('hex');

// Bob生成Diffie-Hellman私钥和公钥
const bob = crypto.createDiffieHellmanGroup(group);
const bobPublicKey = bob.generateKeys('hex');

// 使用PBKDF2从共享密钥派生更强的密钥
const salt = crypto.randomBytes(16); // 随机生成盐值
const iterations = 100000; // 迭代次数
const derivedKeyLength = 32; // 派生密钥的长度

// Alice计算共享密钥的派生值
const aliceSharedSecret = alice.computeSecret(bobPublicKey, 'hex');
const aliceDerivedKey = crypto.pbkdf2Sync(aliceSharedSecret, salt, iterations, derivedKeyLength, 'sha256');

// Bob计算共享密钥的派生值
const bobSharedSecret = bob.computeSecret(alicePublicKey, 'hex');
const bobDerivedKey = crypto.pbkdf2Sync(bobSharedSecret, salt, iterations, derivedKeyLength, 'sha256');

// 使用HMAC对消息进行认证
const message = 'Hello, Word!';  // 要发送的消息(PDF文件)
const aliceHmac = crypto.createHmac('sha256', aliceDerivedKey);  // 使用派生密钥初始化Alice的HMAC
aliceHmac.update(message);  // 更新Alice的HMAC的输入消息
const aliceDigest = aliceHmac.digest('hex');  // 计算Alice的HMAC摘要并返回十六进制字符串

console.log('Alice的派生密钥:', aliceDerivedKey.toString('hex'));
console.log('Bob的派生密钥:', bobDerivedKey.toString('hex'));
console.log('消息:', message);
console.log('HMAC加密数据:', aliceDigest);

// Bob验证消息的完整性
const bobHmac = crypto.createHmac('sha256', bobDerivedKey);  // 使用派生密钥初始化Bob的HMAC
bobHmac.update(message);  // 更新Bob的HMAC的输入消息
const bobDigest = bobHmac.digest('hex');  // 计算Bob的HMAC摘要并返回十六进制字符串

if (aliceDigest === bobDigest) {  // 比较Bob的HMAC摘要与Alice的HMAC摘要是否相同
  console.log('消息完整性验证通过');
} else {
  console.log('消息完整性验证失败');
}
  1. crypto.getDiffieHellman(name):获取一个 Diffie-Hellman 密钥交换对象。
  2. diffieHellman.generateKeys(encoding):生成共享密钥,encoding参数可以用来指定公钥的字符编码。
  3. diffieHellman.getPublicKey(encoding):生成公钥,encoding参数可以用来指定公钥的字符编码。
  4. diffieHellman.getPrivateKey(encoding):生成私钥,encoding参数可以用来指定私钥的字符编码。
  5. diffieHellman.computeSecret(otherPublicKey, inputEncoding, outputEncoding):计算与另一个Diffie-Hellman实体共享的秘钥
  • otherPublicKey:另一个实体的公钥
  • inputEncoding:用于指定输入的字符编码。
  • outputEncoding:参用于指定输出的字符编码。
  1. diffieHellman.getPrime(encoding): 返回Diffie-Hellman算法使用的质数p(也称为"prime")。这个质数是在密钥生成过程中确定的。
  2. diffieHellman.getGenerator(encoding): 返回Diffie-Hellman算法使用的生成器g。生成器是一个小于质数p的数,并且在模p的剩余类群中是一个原根。
  3. curves = crypto.getCurves(curves):获取支持的椭圆曲线列表。
const crypto = require('crypto');


// 创建ECDH对象
const curve = 'secp256k1'; // 曲线参数,可以根据需要选择不同的曲线
const ecdh = crypto.createECDH(curve);

// 生成本地密钥对
ecdh.generateKeys();
const publicKey = ecdh.getPublicKey();

// 使用本地私钥和远程公钥计算共享密钥
const sharedSecret = ecdh.computeSecret(publicKey);

// 使用共享密钥进行密钥派生
const salt = crypto.randomBytes(16); // 随机生成盐值
const derivedKeyLength = 32; // 派生密钥的长度,可以根据实际情况设置
const derivedKey = crypto.pbkdf2Sync(sharedSecret, salt, 100000, derivedKeyLength, 'sha256');

// 使用派生密钥进行HMAC计算
const message = 'Hello, world!';
const hmac = crypto.createHmac('sha256', derivedKey);
hmac.update(message);
const digest = hmac.digest('hex');

console.log('HMAC:', digest);
  1. crypto.getCurves():获取支持的椭圆曲线列表。
  2. curves.generateKeys(encoding):共享密钥,encoding参数可以用来指定公钥的字符编码。
  3. curves.getPublicKey(encoding):生成公钥,encoding参数可以用来指定公钥的字符编码。
  4. curves.getPrivateKey(encoding):生成私钥,encoding参数可以用来指定私钥的字符编码。
  5. curves.computeSecret(otherPublicKey, inputEncoding, outputEncoding):计算与另一个Diffie-Hellman实体共享的秘钥
  • otherPublicKey:另一个实体的公钥
  • inputEncoding:用于指定输入的字符编码。
  • outputEncoding:参用于指定输出的字符编码。
八、辅助函数
  1. crypto.generateKeySync(type,option):
  2. crypto.generateKey(type,option,callback):
  3. crypto.pseudoRandomBytes(size, callback):异步生成伪随机字节的方法
  • size:参数表示要生成的字节数
  • callback:回调函数,用于处理生成的伪随机字节。
  1. crypto.randomBytes(size, callback):异步生成真随机字节的方法
  • size:参数表示要生成的字节数,
  • callbac:回调函数,用于处理生成的真随机字节
  1. crypto.randomFill(buffer, offset, size, callback):异步填充缓冲区的方法
  • buffe:要填充的缓冲区
  • offset:起始偏移量
  • size:要填充的字节数
  • callback:回调函数,用于处理填充后的缓冲区
  1. crypto.randomFillSync(buffer, offset, size):同步填充缓冲区的方法。参数和使用方式与 crypto.randomFill() 方法相同,但是它是同步执行的,不需要回调函数。
  2. crypto.randomInt(min, max, callback):异步生成指定范围内的随机整数的方法
  • min:最小值
  • max:最大值
  • callback:回调函数,用于处理生成的随机整数
  1. crypto.randomUUID(callback):异步生成 UUID v4 的方法。callback 是回调函数,用于处理生成的 UUID。
  2. crypto.generatePrime(candidate, options, callback):生成一个指定长度的素数。
  • candidate:这是一个可选参数,表示要检查的数字。如果未提供,则默认为 undefined。
  • options:这是一个可选参数,用于配置函数的行为。它是一个对象,可以包含以下属性:
  • bitLength:可选的整数,表示要生成的素数的位数。默认值为 20。
  • certainty:可选的整数,表示确定生成的数字为素数的确定性程度。默认值为 20。如果 bitLength 为 20,则 certainty 的默认值为 20。如果 bitLength 大于 20,则 certainty 的默认值为 50。
  • callback:这是一个可选参数,当生成素数完成时会被调用的回调函数。它接受两个参数:一个错误对象和一个生成的素数。
  1. crypto.generatePrimeSync(candidate, options):同步地生成一个指定长度的素数。参数和crypto.generatePrime相同
  2. crypto.checkPrime(candidate, options, callback):异步检查数字是否为素数的方法。
  • candidate: 这是需要检查是否为素数的数字。它可以是整数或字符串。
  • options: 这是一个可选参数,用于配置函数的行为。它是一个对象,可以包含以下属性:
  • bitLength: 这是可选的整数,表示要检查的数字的位数。默认值为 20。
  • certainty: 这是可选的整数,表示确定一个数字是否为素数的确定性程度。默认值为 20。如果 bitLength 为 20,则 certainty 的默认值为 20。如果 bitLength 大于 20,则 certainty 的默认值为 50。
  • callback: 这是可选的回调函数,当检查完成时会被调用。它接受两个参数:一个错误对象和一个布尔值,表示数字是否为素数
  1. crypto.checkPrimeSync(candidate, options):同步检查数字是否为素数的方法。参数和crypto.checkPrime相同

文章来源:https://blog.csdn.net/randy521520/article/details/134348021
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。