《NodeJS开发教程14-Crypto加密与解密》

简介

这节我们来一块研究一下NodeJS提供的关于秘钥(加密和解密)的相关算法API。根据平时常用的加解密算法我归纳了如下四种类别:(算法不止这些这里只是抛砖引玉)

1.内容编解码类(Base64)
2.内容摘要类(MD5、SHA1、SHA256、SHA512)
3.内容加密解密类 又分为:对称加密解密(AES),非对称加密解密(RSA)
4.内容签名类(RSA+SHA1 或 RSA+SHA256 或 RSA+MD5等等)

NodeJS中处理秘钥相关的模块是 crypto ,需要首先引入

/*crypto加密解密*/
let crypto;
try {
    crypto = require('crypto');//如果不支持 crypto模块则会抛出异常

    ......//进行编解码操作
}catch (err) {
    console.log('不支持 crypto!');
}

1.内容编解码类

  • Base64编解码

Base64编解码其实算不上是加密解密算法,顶多算是一种编解码算法,因为Base64算法首先是可逆的,而且是非常容易被破译的,所以我们一般用Base64都是去编码信息内容,基本不用它去加密,即使加了也和没加一样,呵呵。。。接下来晒出nodejs进行Base64编解码示例:

 //BASE64编解码
    //编码
    var bc = new Buffer("Base64编解码内容");
    var bec = bc.toString("base64");
    console.log("Base64编码后结果: %s",bec);
//log打印:Base64编码后结果: QmFzZTY057yW6Kej56CB5YaF5a65
    //解码
    var bdc = new Buffer(bec, "base64");
    var bdcs = bdc.toString();
    console.log("Base64解码后结果: %s",bdcs);
 //log打印:Base64解码后结果: Base64编解码内容

2.内容摘要类(MD5、SHA1、SHA256、SHA512)

摘要算法又称哈希/散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。算法不可逆。
摘要一般用作验证内容的完整性,真实性(比如我们上传一个压缩文件使用MD5进行加密,得到一个摘要串,下载我们这个压缩文件的一方只需要同样使用MD5算法进行加密后,得到摘要串和我们上传时得到的摘要串做对比,一致则说明下载的文件是完整的可信的,可以放心使用!_
接下来我列举几个NodeJS的摘要算法:

  • MD5加密摘要算法使用
    //MD5-产生128位的加密结果【不可逆】
    var hash_md5=crypto.createHash("md5");
    hash_md5.update("加密内容ABCD1234");
    var md5c=hash_md5.digest("hex");
    console.log("MD5加密后结果: %s",md5c);

    log输出:MD5加密后结果: 84111fcac08f3a3e30c5df95cf6585a4

这里标记一下update()这个方法,它可以追加内容字符串,追加后得到的摘要结果和上面得到的结果是一样的:

    //md5-update追加字符串(不可逆)
    hash_md5=crypto.createHash("md5");
    hash_md5.update("加密内容");
    hash_md5.update("ABCD");
    hash_md5.update("1234");
    md5c=hash_md5.digest("hex");
    console.log("MD5update追加:%s",md5c);

    log输出:MD5update追加:84111fcac08f3a3e30c5df95cf6585a4
  • SHA1加密摘要算法使用
    //SHA1-产生160位的加密结果【不可逆】
    var hash_sha1=crypto.createHash("sha1");
    hash_sha1.update("加密内容ABCD1234");
    var sha1c=hash_sha1.digest("hex");//显示为16进制
    console.log("SHA1加密后结果:%s",sha1c);

    log输出:SHA1加密后结果:f4c1ec92573c29e0220b82f81cb33f304116391d
  • SHA256加密摘要算法使用
   //SHA256-产生256位的加密结果【不可逆】
    var hash_sha256=crypto.createHash("sha256");
    hash_sha256.update("加密内容ABCD1234");
    var sha256c=hash_sha256.digest("hex");//显示为16进制
    console.log("SHA256加密后结果:%s",sha256c);

    log输出:SHA256加密后结果:e7c9f5967b1d9e5a997aeb18d8555d5de7a284a9c7e6deb296b90492bc48dd79
  • SHA256加密(Hmac方式)
    HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。
    HMAC这种方式(需要额外key)要比传统摘要方式(不需要额外key)更加保密,不易破解!
    除了支持SHA256还支持其它HMAC方式的摘要算法,比如SHA1、SHA512、MD5等。
    //sha256加密(Hmac方式)拥有一个加密Key,这样更安全一些
    const secret="AK41abud";//秘钥
    var hmac=crypto.createHmac("sha256",secret);
    var content=hmac.update("加密内容ABCD1234");
    var cryptoContent=content.digest("hex");
    console.log("sha256(Hmac方式)加密后结果:%s",cryptoContent);

    log输出:sha256(Hmac方式)加密后结果:b4e164a61eb1d0dd532988fe5448d47d65f1ee4d6caf6132200727d1d81dddc4

3.内容加密解密类又分为: 对称加密解密(AES),非对称加密解密(RSA)

对信息进行加密解密,有很多种算法,当然不只是AES和RSA这两种,这两种只是我们平时比较常用的。
加密解密算法,大致又分为对称加密和非对称加密两大类,当然这些加密算法都是可逆的,如果像上面介绍的MD5、SHA1是不可逆的,那我们把内容加完秘后解不开了,不就悲剧了。。。呵呵

  • AES对称加密
    对称加密大概可以理解为,加密和解密,使用的是同一个秘钥key。
    //AES对称加密
    var secretkey="passwd";//唯一(公共)秘钥
    var content="需要加密的内容ABC";
    var cipher=crypto.createCipher('aes192', secretkey);//使用aes192加密
    var enc=cipher.update(content,"utf8","hex");//编码方式从utf-8转为hex;
    enc+=cipher.final('hex');//编码方式转为hex;
    //
    //AES对称解密
    var decipher=crypto.createDecipher('aes192', secretkey);
    var dec=decipher.update(enc,"hex", "utf8");
    dec+=decipher.final("utf8");
    console.log("AES对称解密结果:"+dec);

    log输出:AES对称解密结果:需要加密的内容ABC
  • RSA非对称加密
    非对称加密大致可以这样理解:加密和解密,使用的是不同的秘钥,通常我们使用算法会得到一对秘钥(一个叫做私钥,另一个叫做公钥),公钥一般用来进行加密,而私钥一般用来进行解密,当然你也可以颠倒过来使用,私钥加密公钥解密都是可以的(只是一般不这么使用)。

接下来我介绍一下在nodejs中如何使用RSA进行加密和解密:

  • 首先我们需要得到公钥和私钥:
    使用OpenSSL算法可以得到RSA公钥和私钥(如果没安装OpenSSL,可以百度一下先安装一下)

安装好OpenSSL后cmd生成RSA私钥:

openssl genrsa -out privatekey.pem 1024

cmd再生成公钥:

openssl rsa -in privatekey.pem -pubout -out publickey.pem

这样在当前目录中就会生成 ‘privatekey.pem’(私钥) 和 ‘publickey.pem’ (公钥)这两个文件,之后我们就使用这两个文件进行RSA非对称加密和解密。

 //RSA非对称加密解密
   const fs=require("fs");

    const privatepem2=fs.readFileSync("./privatekey.pem");//私有key【需要 pem 编码的key】server.pem
    const publicpem2=fs.readFileSync("./publickey.pem");//公有key【需要 pem 编码的key】cert.pem
    const prikey2=privatepem2.toString();
    const pubkey2=publicpem2.toString();
    // 加密方法
    var encrypt = (data, key) => {
        // 注意,第二个参数是Buffer类型
        return crypto.publicEncrypt(key, Buffer.from(data));
    };
    // 解密方法
    var decrypt = (encrypted, key) => {
        // 注意,encrypted是Buffer类型
        return crypto.privateDecrypt(key, encrypted);
    };

    const plainText = "我是RSA非对称加密字符串内容";
    const crypted = encrypt(plainText, pubkey2); // 加密
    const decrypted = decrypt(crypted, prikey2); // 解密
    console.log("RSA非对称解密结果:%s",decrypted.toString());

    log输出:RSA非对称解密结果:我是RSA非对称加密字符串内容

4.内容签名类(RSA+SHA1 或 RSA+SHA256 或 RSA+MD5等等)

“信息内容签名”其实和我们日常中对纸质文件进行签名是一个道理。又称为“数字签名”,包括报文摘要。报文摘要和非对称加密一起,提供数字签名的方法。

数字签名主要是保证信息的完整和提供信息发送者的身份认证和不可抵赖性,这其中,“完整性”主要就是由报文摘要提供的,报文摘要就是用来防止发送的报文被篡改。

使用流程:

  • 使用RSA私钥进行签名(对信息报文生成的摘要进行私钥签名)生成签名串,一般是16进制字符串
  • 使用RSA公钥进行签名校验(验明正身)

其实很好理解,你可以想象成我们手签的名字,通过独一无二的书写字体去验证是否是出自于你的笔记。。。

    //非对称签名校验
    const privatepem=fs.readFileSync("./privatekey.pem");//私有key【需要 pem 编码的key】server.pem
    const publicpem=fs.readFileSync("./publickey.pem");//公有key【需要 pem 编码的key】cert.pem
    const otherkeys=require("./otherkeys.js");//其它公钥和私钥(测试用,如果用其它的公钥进行校验签名肯定是无法通过的)

    const prikey=privatepem.toString();
    const pubkey=publicpem.toString();

    var data = "我是信息内容摘要"
    var sign = crypto.createSign('RSA-SHA256');//创建签名算法
    sign.update(data);
    var sig = sign.sign(prikey, 'hex');//得到签名

    var verify = crypto.createVerify('RSA-SHA256');
    verify.update(data);
    var t=verify.verify(pubkey, sig, 'hex');
    // var t=verify.verify(otherkeys.pubKey, sig, 'hex');//用其它公钥校验无法通过!
    console.log("非对称签名校验结果结果:"+t);

    log输出:非对称签名校验结果结果:true

这里我把其它的公钥和秘钥对也贴出来,otherkeys.js内容:

//其它私钥和公钥
exports.privKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDFWnl8fChyKI/Tgo1ILB+IlGr8ZECKnnO8XRDwttBbf5EmG0qV
8gs0aGkh649rb75I+tMu2JSNuVj61CncL/7Ct2kAZ6CZZo1vYgtzhlFnxd4V7Ra+
aIwLZaXT/h3eE+/cFsL4VAJI5wXh4Mq4Vtu7uEjeogAOgXACaIqiFyrk3wIDAQAB
AoGBAKdrunYlqfY2fNUVAqAAdnvaVOxqa+psw4g/d3iNzjJhBRTLwDl2TZUXImEZ
QeEFueqVhoROTa/xVg/r3tshiD/QC71EfmPVBjBQJJIvJUbjtZJ/O+L2WxqzSvqe
wzYaTm6Te3kZeG/cULNMIL+xU7XsUmslbGPAurYmHA1jNKFpAkEA48aUogSv8VFn
R2QuYmilz20LkCzffK2aq2+9iSz1ZjCvo+iuFt71Y3+etWomzcZCuJ5sn0w7lcSx
nqyzCFDspQJBAN3O2VdQF3gua0Q5VHmK9AvsoXLmCfRa1RiKuFOtrtC609RfX4DC
FxDxH09UVu/8Hmdau8t6OFExcBriIYJQwDMCQQCZLjFDDHfuiFo2js8K62mnJ6SB
H0xlIrND2+/RUuTuBov4ZUC+rM7GTUtEodDazhyM4C4Yq0HfJNp25Zm5XALpAkBG
atLpO04YI3R+dkzxQUH1PyyKU6m5X9TjM7cNKcikD4wMkjK5p+S2xjYQc1AeZEYq
vc187dJPRIi4oC3PN1+tAkBuW51/5vBj+zmd73mVcTt28OmSKOX6kU29F0lvEh8I
oHiLOo285vG5ZtmXiY58tAiPVQXa7eU8hPQHTHWa9qp6
-----END RSA PRIVATE KEY-----
`;

exports.pubKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFWnl8fChyKI/Tgo1ILB+IlGr8
ZECKnnO8XRDwttBbf5EmG0qV8gs0aGkh649rb75I+tMu2JSNuVj61CncL/7Ct2kA
Z6CZZo1vYgtzhlFnxd4V7Ra+aIwLZaXT/h3eE+/cFsL4VAJI5wXh4Mq4Vtu7uEje
ogAOgXACaIqiFyrk3wIDAQAB
-----END PUBLIC KEY-----
`;

这里只给出一种签名算法,其实NodeJS为我们还提供了很多其它的签名算法,具体可以查看官方API文档。
签名算法,我们在平时用的还是很多的,比如 微信支付、支付宝支付等等,使用签名需要去验明信息来源身份的有效性,这样使我们的信息传递交互更安全可靠!!

谢谢大家!共勉!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容