散列(哈希)算法

散列算法也叫哈希算法,用来把任意长度的输入变换成固定长度的输出,常见的有md5,sha1等

  • 相同的输入会产生相同的输出
  • 不同的输出会产生不同的输出
  • 任意的输入长度输出长度是相同的
  • 不能从输出推算出输入的值

image.png

获取所有的散列算法

  1. console.log(crypto.getHashes());

语法说明

  1. crypto.createHash(algorithm);//创建HASH对象
  2. hash.update(data,[input_encoding]);//增加要添加摘要的数据,摘要输出前可以使用多次update
  3. hash.digest([encoding]);//输出摘要内容,输出后则不能再添加摘要内容

散列算法示例

  1. var crypto = require('crypto');
  2. var md5 = crypto.createHash('md5');//返回哈希算法
  3. var md5Sum = md5.update('hello');//指定要摘要的原始内容,可以在摘要被输出之前使用多次update方法来添加摘要内容
  4. var result = md5Sum.digest('hex');//摘要输出,在使用digest方法之后不能再向hash对象追加摘要内容。
  5. console.log(result);

多次update

  1. var fs = require('fs');
  2. var shasum = crypto.createHash('sha1');//返回sha1哈希算法
  3. var rs = fs.createReadStream('./readme.txt');
  4. rs.on('data', function (data) {
  5. shasum.update(data);//指定要摘要的原始内容,可以在摘要被输出之前使用多次update方法来添加摘要内容
  6. });
  7. rs.on('end', function () {
  8. var result = shasum.digest('hex');//摘要输出,在使用digest方法之后不能再向hash对象追加摘要内容。
  9. console.log(result);
  10. })

HMAC算法

对称加密

image.png

  1. var crypto = require('crypto');
  2. var fs = require('fs');
  3. let str = 'hello';
  4. let cipher = crypto.createCipher('blowfish', fs.readFileSync(path.join(__dirname, 'rsa_private.key')));
  5. let encry = cipher.update(str, 'utf8','hex');
  6. encry += cipher.final('hex');
  7. console.log(encry);
  8. let deciper = crypto.createDecipher('blowfish', fs.readFileSync(path.join(__dirname, 'rsa_private.key')));
  9. let deEncry = deciper.update(encry, 'hex','utf8');
  10. deEncry += deciper.final('utf8');
  11. console.log(deEncry);

非对称加密算法

  • 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)
  • 公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密,如果私钥加密,只能公钥解密
  • 因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法

image.png

  1. openssl rsa -in rsa_private.key -pubout -out rsa_public.key
  2. var crypto = require('crypto');
  3. var fs = require('fs');
  4. let key = fs.readFileSync(path.join(__dirname, 'rsa_private.key'));
  5. let cert = fs.readFileSync(path.join(__dirname, 'rsa_public.key'));
  6. let secret = crypto.publicEncrypt(cert, buffer);//公钥加密
  7. let result = crypto.privateDecrypt(key, secret);//私钥解密
  8. console.log(result.toString());

签名

在网络中,私钥的拥有者可以在一段数据被发送之前先对数据进行签名得到一个签名 通过网络把此数据发送给数据接收者之后,数据的接收者可以通过公钥来对该签名进行验证,以确保这段数据是私钥的拥有者所发出的原始数据,且在网络中的传输过程中未被修改。

image.png

  1. let private = fs.readFileSync(path.join(__dirname, 'rsa_private.key'), 'ascii');
  2. let public = fs.readFileSync(path.join(__dirname, 'rsa_public.key'), 'ascii');
  3. let str = 'zhufengpeixun';
  4. let sign = crypto.createSign('RSA-SHA256');
  5. sign.update(str);
  6. let signed = sign.sign(private, 'hex');
  7. let verify = crypto.createVerify('RSA-SHA256');
  8. verify.update(str);
  9. let verifyResult = verify.verify(public,signed,'hex'); //true