一、Hash(摘要)
- ①摘要(digest):将长度不固定的消息作为输入,通过运行hash函数,生成固定长度的输出,这段输出就叫做摘要。通常用来验证消息完整、未被篡改。
- ②摘要运算是不可逆的。也就是说,输入固定的情况下,产生固定的输出。但知道输出的情况下,无法反推出输入。
- ③常见的摘要算法 与 对应的输出位数如下:
MD5:128位
SHA-1:160位
SHA256 :256位
SHA512:512位 -
crypto.createHash()
方法用于创建Hash
实例。Hash
不能直接使用new
关键字创建对象。
方法
-
hash.digest([encoding]):
计算所有传入数据的hash摘要。参数encoding(编码方式)可以为hex
,binary
或者base64
。 -
hash.update(data[, inputEncoding]):
更新hash的内容为指定的data。当使用流数据时可能会多次调用该方法。
var crypto = require('crypto');
var md5 = crypto.createHash('md5');
var message1 = 'hello';
var message2 = ' world';
var digest = md5.update(message1, 'utf8')
.update(message2, 'utf8')
.digest('hex');
console.log(digest);
二、MAC、HMAC
- MAC(Message Authentication Code):消息认证码,用以保证数据的完整性。运算结果取决于消息本身、秘钥。
- MAC可以有多种不同的实现方式,比如HMAC。
- HMAC(Hash-based Message Authentication Code):可以粗略地理解为带秘钥的hash函数。
-
crypto.createHmac()
方法用来创建Hmac
实例。Hmac
不能直接使用new
关键字创建对象。
方法
-
crypto.createHmac(algorithm, key[, options]):
前两个参数为摘要函数、秘钥 hmac.digest([encoding]):
hmac.update(data[, inputEncoding]):
const crypto = require('crypto');
let hmac = crypto.createHmac('md5', '123456');
let ret = hmac.update('hello').digest('hex');
console.log(ret);
// 9c699d7af73a49247a239cb0dd2f8139
三、对称加密(Cipher加密、Decipher解密)
Cipher
- 作为stream,既可读又可写
-
crypto.createCipher()
或crypto.createCipheriv()
方法用于创建Cipher
实例。Cipher
对象不能直接使用new
关键字创建。 -
crypto.createCipher(algorithm, password[, options]):
algorithm 表示用何种加密算法,常见的对称加密算法:DES、3DES、AES、Blowfish、RC5、IDEA。
使用Cipher对象作为流:
const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');
let encrypted = '';
cipher.on('readable', () => {
const data = cipher.read();
if (data)
encrypted += data.toString('hex');
});
cipher.on('end', () => {
console.log(encrypted);
// Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504
});
cipher.write('some clear text data');
cipher.end();
使用Cipher和管道流:
const crypto = require('crypto');
const fs = require('fs');
const cipher = crypto.createCipher('aes192', 'a password');
const input = fs.createReadStream('test.js');
const output = fs.createWriteStream('test.enc');
input.pipe(cipher).pipe(output);
方法
cipher.update(data[, inputEncoding][, outputEncoding]):
inputEncoding:必须是`'utf8'`, `'ascii'`, 或者`'latin1'`
`data`是`Buffer`,`TypedArray`, 或者`DataView`则忽略inputEncoding
`outputEncoding`可以是`'latin1'`, `'base64'` 或者 `'hex'`。不指定则返回`Buffer`
cipher.final([outputEncoding]):
const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');
let encrypted = cipher.update('some clear text data', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504
-
cipher.setAutoPadding([autoPadding]):
当使用块加密算法时,Cipher类会自动添加padding到输入数据中,来适配相应块大小。可调用cipher.setAutoPadding(false)禁用默认padding。
Decipher
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
let decrypted = '';
decipher.on('readable', () => {
const data = decipher.read();
if (data)
decrypted += data.toString('utf8');
});
decipher.on('end', () => {
console.log(decrypted);
// Prints: some clear text data
});
const encrypted =
'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
decipher.write(encrypted, 'hex');
decipher.end();
//===============================================
const crypto = require('crypto');
const fs = require('fs');
const decipher = crypto.createDecipher('aes192', 'a password');
const input = fs.createReadStream('test.enc');
const output = fs.createWriteStream('test.js');
input.pipe(decipher).pipe(output);
//===============================================
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
const encrypted =
'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data
四、签名(Signer 和 Verify)
Signer
- Sign”类是生成签名的实用工具。
- crypto.createSign(algorithm [,options])用于创建Sign实例。Sign实例不能直接使用new关键字创建。
- 使用“符号”对象作为流:
const crypto = require('crypto');
const sign = crypto.createSign('SHA256');
sign.write('some data to sign');
sign.end();
const privateKey = getPrivateKeySomehow();
console.log(sign.sign(privateKey, 'hex'));
// Prints: the calculated signature using the specified private key and
// SHA-256. For RSA keys, the algorithm is RSASSA-PKCS1-v1_5 (see padding
// parameter below for RSASSA-PSS). For EC keys, the algorithm is ECDSA.
方法
sign.sign(privateKey[, outputFormat]):
sign.update(data[, inputEncoding]):
:
const crypto = require('crypto');
const sign = crypto.createSign('SHA256');
sign.update('some data to sign');
const privateKey = getPrivateKeySomehow();
console.log(sign.sign(privateKey, 'hex'));
// Prints: the calculated signature
Verify
- Verify类是验证签名的工具。
-
crypto.createVerify(algorithm[, options])
方法用于创建Verify
实例。Verify
对象不能直接使用new
关键字创建。 - 使用“验证”对象作为流:
const crypto = require('crypto');
const verify = crypto.createVerify('SHA256');
verify.write('some data to sign');
verify.end();
const publicKey = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(publicKey, signature));
// Prints: true or false
//=========================================
const crypto = require('crypto');
const verify = crypto.createVerify('SHA256');
verify.update('some data to sign');
const publicKey = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(publicKey, signature));
// Prints: true or false
五、非对称加密
- 加密/解密:给定明文,通过一定的算法,产生加密后的密文,这个过程叫加密。反过来就是解密。
1、非对称加密
- 对称加密速度要快于非对称加密。
- 非对称加密通常用于加密短文本,对称加密通常用于加密长文本。
- 两者可以结合起来使用,比如HTTPS协议,可以在握手阶段,通过RSA来交换生成对称秘钥。在之后的通讯阶段,可以使用对称加密算法对数据进行加密,秘钥则是握手阶段生成的。
- 常见的非对称加密算法:RSA、DSA、ElGamal。
方法
-
crypto.publicEncrypt(key,buffer):
公钥加密 -
crypto.privateEncrypt(privateKey, buffer):
私钥加密
-
crypto.publicDecrypt(key,buffer):
公钥解密 -
crypto.privateDecrypt(privateKey, buffer):
私钥解密
网友评论