官方介绍:crypto
模块提供了加密功能,包含对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证功能的一整套封装。
https://www.nodeapp.cn/crypto.html
所以为什么加密?加密是什么?怎么才能进行加密?(3W原则)
Why?
一句话--为了安全。。。
What?
加密就是对数据的操作,通过加密算法,将数据进行转换,nodejs提供了关于秘钥的相关算法API,分为四种类别:
- 内容编码类(base64)
- 内容摘要类(MD5、SHA1、SHA256、SHA512、SHA2、SHA3)
- 内容加密解密类(分为对称加密解密(AES)、非对称加密解密(RSA))
- 内容签名类(RSA+S)
How?
在Nodejs中为我们提供了加密模块 crypto 通过 require进行引入即可
const crypto = require('crypto')
1.内容编码类(base64)....
勉强算的上是加密吧。。如果外行人来看的话,会以为是加密,其实就是一种编解码算法,因为base64是可逆的,所以
容易被破解,通过一些简单的操作。。一般用它去编码信息内容,而不选择用它加密,因为不安全。上代码::
//加密
var str = Buffer.from('我最帅')
console.log(str.toString('base64')) //5oiR5piv54i454i4
//解密
var deStr = Buffer.from(str,'base64');
console.log(deStr.toString()) //我最帅
2.内容摘要类(MD5、SHA1、SHA2、SHA3、SHA256、SHA512)
摘要算法也叫哈希算法或者散列算法、通过一个函数、把任意长度的数据转换城一个固定的数据串
不可逆、一般用来验证内容的完整性、真实性;打个比方、我们上传一张图片,然后用MD5算法进行加密
得到一个摘要串、然后下载方一样使用MD5进行加密,也获得了一个摘要串、如果两个摘要串是一样的、
证明文件完整,没有毛病、摘要穿通常是一个16进制的字符串;
MD5:
const crypto = require('crypto') // 引入加密模块
var md5 = crypto.createHash('md5'); //创建 MD5算法
md5.update('我最帅'); // 加密数据
md5.update('追加内容:我是大帅哥'); //追加数据
var result = md5.digest('hex'); // 加密结果
console.log('md5加密后的字符串:'+result)
SHA2:
const crypto = require('crypto'); //引入加密模块
var sha1 = crypto.createHash('sha1')//创建sha1算法
sha1.update('我最帅')//上传需要加密的信息
var result = sha1.digest('hex')//输出
console.log('sha1加密后的字符串:'+result)//打印加密后的数据
//sha1加密后的字符串:ba74c6401377451106ec5d4c0b0cae161e08e8c7
SHA256:
//不做解释。。。与sha1同理。。
const crypto = require('crypto');
var sha256 = crypto.createHash('sha256')
sha1.update('我最帅')
var result = sha256.digest('hex')
console.log('sha256加密后的字符串:'+result)
//sha256加密后的字符串:30350c51eda98987695f1a513756a670f7126f328899000ebdc4ec8fcccb083f
类似的算法有很多。。。感冒的同学可以自己打印看看:
console.log(crypto.getHashes())//获取所有支持的hash算法列表
[
'RSA-MD4',
'RSA-MD5',
'RSA-MDC2',
'RSA-RIPEMD160',
'RSA-SHA1',
'RSA-SHA1-2',
'RSA-SHA224',
'RSA-SHA256',
'RSA-SHA3-224',
'RSA-SHA3-256',
'RSA-SHA3-384',
'RSA-SHA3-512',
'RSA-SHA384',
'RSA-SHA512',
'RSA-SHA512/224',
'RSA-SHA512/256',
'RSA-SM3',
'blake2b512',
'blake2s256',
'id-rsassa-pkcs1-v1_5-with-sha3-224',
'id-rsassa-pkcs1-v1_5-with-sha3-256',
'id-rsassa-pkcs1-v1_5-with-sha3-384',
'id-rsassa-pkcs1-v1_5-with-sha3-512',
'md4',
'md4WithRSAEncryption',
'md5',
'md5-sha1',
'md5WithRSAEncryption',
'mdc2',
'mdc2WithRSA',
'ripemd',
'ripemd160',
'ripemd160WithRSA',
'rmd160',
'sha1',
'sha1WithRSAEncryption',
'sha224',
'sha224WithRSAEncryption',
'sha256',
'sha256WithRSAEncryption',
'sha3-224',
'sha3-256',
'sha3-384',
'sha3-512',
'sha384',
'sha384WithRSAEncryption',
'sha512',
'sha512-224',
'sha512-224WithRSAEncryption',
'sha512-256',
'sha512-256WithRSAEncryption',
'sha512WithRSAEncryption',
'shake128',
'shake256',
'sm3',
'sm3WithRSAEncryption',
'ssl3-md5',
'ssl3-sha1',
'whirlpool'
]
以上的加密都是不基于key的加密方式,演示一个使用key加密的方式:
SHA256加密(Hmac方式)
HMAC是与密钥相关的哈希算法消息认证,也就是仍然基于哈希算法,但是是以一个密钥和一个消息
为输入、生成消息摘要输出、其好处就是比上面说的那些加密手段更加保密、不容易被破解,除了SHA256
还有SHA1、SHA2、MD5等算法都可以使用Hmac的方式进行加密;上代码:
const crypto = require('crypto'); //引入加密模块
const secret = 'zheshimima'//生成key
var hamc = crypto.createHmac('sha256',secret);//创建Hmac传入加密手段和密钥
var content = hamc.update('我真帅')//传入需要加密的字符
var result = content.digest('hex');//生成摘要
console.log('通过key加密后的结果为:'+result)
//通过key加密后的结果为:b09658dc27d17577834a220b1997b7c717e8010d4de036c5f3efb921820f53bc
3.内容加密解密分类:对称加密(AES) 非对称加密(RSA)
对数据的加密解密不知这两种、这两种比较广泛、都是可逆的加密算法,以上的算法都是不可逆的,除了Base64....你如果要抬杠的话。。
先说对称加密:
对称加密解密就是 加密与解密使用同一个key (密钥)
const crypto = require('crypto');
const secret = 'zheshimiyao'
var cipher = crypto.createCipher('aes192',secret);//使用aes192
var enc = cipher.update('我最帅','utf8','hex');//编码从utf-8转为hex
enc+=cipher.final('hex')
console.log('加密后的结果'+enc)//加密后的结果62312c598b18e4db119df9cd51fbd105
//对称解密 AES
var decipher = crypto.createDecipher('aes192',secret);
var dec = decipher.update(enc,'hex','utf8');
dec+=decipher.final('utf8');
console.log('解密后的结果'+dec)//解密后的结果我最帅
然后是非对称加密:
非对称加密的话,聪明的你应该可以猜到了。就是加密的密钥很你解密的密钥不是同一个,所以叫非对称加密解密,所以
我们这时候就需要一个公钥对明文进行加密,变成暗文,然后利用一个私钥进行解密。开始秀操作了:
首先执行命令: openssl 如果说报错了。证明缺少openssl这个命令,自行百度解决安装,这里不做解释
生成私钥:
genrsa -out private_key.pem 1024
生成公钥:
rsa -in private_key.pem -pubout -out public_key.pem
目录中此时会生成 private_key.pem 与 public_key.pem 两个pem 文件,分别存放私钥与公钥,然后我们使用这两个东西进行加密与解密:
const crypto = require('crypto');
const fs = require('fs'); //利用fs模块对 .pem 文件进行读取
const private_key = fs.readFileSync('./privatekey.pem').toString();//私钥 key
const public_key = fs.readFileSync('./publickey.pem').toString();//公钥 key
function encrypto(key,data) { // 加密函数
//key : 公钥 data:需要加密的数据,buffer格式
return crypto.publicEncrypt(key,Buffer.from(data));
}
function decrypto(key,encrypted) { //解密函数
//key : 私钥 encrypted: 解密的数据 , buffer格式
return crypto.privateDecrypt(key,encrypted)
}
const str = '我真帅'//需要加密的
const cryptoed = encrypto(public_key,str) //公钥加密
const decryptoed = decrypto(private_key,cryptoed) //私钥解密
console.log('加密后的数据摘要:'+cryptoed.toString('base64'));
/**
* 加密后的数据摘要:dPAS1Ifyb2rW4B56wVikTBPjigKHrlMyabJsImb2mjqqsZ4LhFCSA0IC8fmun1Vs1ErQUrYf74C+/d
7mWH3g57haUIxF/WvIXLswq1hJ4b1xNxNio6/Qi9Ii3saJJQrFt4qGkWVYsvyeLB/QHYetlCh9c4GWL0C+CTCnXzRcfRA=
*/
console.log('解密后的摘要:'+decryptoed.toString('utf8'))
/**
* 解密后的摘要:我真帅
*/
4.内容签名类 (数字签名)
这主要说一下加解密签名验证,通过RSA的方式加密签名,然后解密签名进行验证,用这种方式,使信息不可抵赖,生活中
像银行等机构都需要用户签名,在网络通信种采取数字签名的方式实现信息的不可否认,还有就是确认发送信息方的身份,:
const crypto = require('crypto');
const fs =require('fs')
const privateKey = fs.readFileSync('./privatekey.pem')
const publicKey = fs.readFileSync('./publickey.pem')
let str = '我是摘要'
var sign = crypto.createSign('RSA-SHA3-224');
//官方解释:创建并返回使用给定算法的符号对象。使用crypto.gethashes()获取可用签名算法的名称数组。可选选项参数控制流。可写行为。
sign.update(str)
var signResult = sign.sign(privateKey,'hex')
console.log('签名:'+signResult)
/**
通过公钥生成加密签名:签名:
//RSA-SHA3-224
4662212d04d0ce0546ae54e68f1aa5e3dbd6f8f4d60cb933a4fff26f1a088bb70b6cf137555b346b39b261ede8
f3891fd08311b67e8e5e394186c1d15641d394d7d26848f26f393bdca7f8ae9419668777b81762676d06377d9b33433177ddc74e42245e73bc3ac6d4475193eab65b006781caafe85343f7baf0593ef8d0851d
//RSA-SHA512
79a6b54a46fa55a71589372029600484b13b741d60abb07ceea6dc876dd865dd8b2fe253965ab1b9f78b6d6d8a 2a06bcf6326f2e7f7329254a2c4a309fcd10c0cf33729e98c8f7902f76f3e6512342d4f7bc3ad58c9e48d7ff49bd94e7c7f29fade95a44bd4a455d6a64bd51371e4d5832f68049265213c8f1d54dc599ee5e4d
*
*/
var verify = crypto.createVerify('RSA-SHA3-224')
verify.update(str)
var verifyResult = verify.verify(publicKey,signResult,'hex')
console.log('签名验证结果'+verifyResult);
数字签名的应用场景主要是在支付功能时确认信息来源方的身份,增加安全性、可靠性
码字不易,记得点赞!
码字不易,记得点赞!
码字不易,记得点赞!
码字不易,记得点赞!