《NodeJS開發(fā)教程14-Crypto加密與解密》

簡介

這節(jié)我們來一塊研究一下NodeJS提供的關(guān)于秘鑰(加密和解密)的相關(guān)算法API。根據(jù)平時常用的加解密算法我歸納了如下四種類別:(算法不止這些這里只是拋磚引玉)

1.內(nèi)容編解碼類(Base64)
2.內(nèi)容摘要類(MD5、SHA1践剂、SHA256森爽、SHA512)
3.內(nèi)容加密解密類 又分為:對稱加密解密(AES)测暗,非對稱加密解密(RSA)
4.內(nèi)容簽名類(RSA+SHA1 或 RSA+SHA256 或 RSA+MD5等等)

NodeJS中處理秘鑰相關(guān)的模塊是 crypto 馁害,需要首先引入

/*crypto加密解密*/
let crypto;
try {
    crypto = require('crypto');//如果不支持 crypto模塊則會拋出異常

    ......//進行編解碼操作
}catch (err) {
    console.log('不支持 crypto!');
}

1.內(nèi)容編解碼類

  • Base64編解碼

Base64編解碼其實算不上是加密解密算法,頂多算是一種編解碼算法脱货,因為Base64算法首先是可逆的,而且是非常容易被破譯的律姨,所以我們一般用Base64都是去編碼信息內(nèi)容振峻,基本不用它去加密,即使加了也和沒加一樣择份,呵呵扣孟。。荣赶。接下來曬出nodejs進行Base64編解碼示例:

 //BASE64編解碼
    //編碼
    var bc = new Buffer("Base64編解碼內(nèi)容");
    var bec = bc.toString("base64");
    console.log("Base64編碼后結(jié)果: %s",bec);
//log打印:Base64編碼后結(jié)果: QmFzZTY057yW6Kej56CB5YaF5a65
    //解碼
    var bdc = new Buffer(bec, "base64");
    var bdcs = bdc.toString();
    console.log("Base64解碼后結(jié)果: %s",bdcs);
 //log打印:Base64解碼后結(jié)果: Base64編解碼內(nèi)容

2.內(nèi)容摘要類(MD5凤价、SHA1、SHA256拔创、SHA512)

摘要算法又稱哈希/散列算法利诺。它通過一個函數(shù),把任意長度的數(shù)據(jù)轉(zhuǎn)換為一個長度固定的數(shù)據(jù)串(通常用16進制的字符串表示)伏蚊。算法不可逆立轧。
摘要一般用作驗證內(nèi)容的完整性,真實性(比如我們上傳一個壓縮文件使用MD5進行加密躏吊,得到一個摘要串氛改,下載我們這個壓縮文件的一方只需要同樣使用MD5算法進行加密后,得到摘要串和我們上傳時得到的摘要串做對比比伏,一致則說明下載的文件是完整的可信的胜卤,可以放心使用!_
接下來我列舉幾個NodeJS的摘要算法:

  • MD5加密摘要算法使用
    //MD5-產(chǎn)生128位的加密結(jié)果【不可逆】
    var hash_md5=crypto.createHash("md5");
    hash_md5.update("加密內(nèi)容ABCD1234");
    var md5c=hash_md5.digest("hex");
    console.log("MD5加密后結(jié)果: %s",md5c);

    log輸出:MD5加密后結(jié)果: 84111fcac08f3a3e30c5df95cf6585a4

這里標記一下update()這個方法赁项,它可以追加內(nèi)容字符串葛躏,追加后得到的摘要結(jié)果和上面得到的結(jié)果是一樣的:

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

    log輸出:MD5update追加:84111fcac08f3a3e30c5df95cf6585a4
  • SHA1加密摘要算法使用
    //SHA1-產(chǎn)生160位的加密結(jié)果【不可逆】
    var hash_sha1=crypto.createHash("sha1");
    hash_sha1.update("加密內(nèi)容ABCD1234");
    var sha1c=hash_sha1.digest("hex");//顯示為16進制
    console.log("SHA1加密后結(jié)果:%s",sha1c);

    log輸出:SHA1加密后結(jié)果:f4c1ec92573c29e0220b82f81cb33f304116391d
  • SHA256加密摘要算法使用
   //SHA256-產(chǎn)生256位的加密結(jié)果【不可逆】
    var hash_sha256=crypto.createHash("sha256");
    hash_sha256.update("加密內(nèi)容ABCD1234");
    var sha256c=hash_sha256.digest("hex");//顯示為16進制
    console.log("SHA256加密后結(jié)果:%s",sha256c);

    log輸出:SHA256加密后結(jié)果:e7c9f5967b1d9e5a997aeb18d8555d5de7a284a9c7e6deb296b90492bc48dd79
  • SHA256加密(Hmac方式)
    HMAC是密鑰相關(guān)的哈希運算消息認證碼,HMAC運算利用哈希算法悠菜,以一個密鑰和一個消息為輸入舰攒,生成一個消息摘要作為輸出。
    HMAC這種方式(需要額外key)要比傳統(tǒng)摘要方式(不需要額外key)更加保密悔醋,不易破解摩窃!
    除了支持SHA256還支持其它HMAC方式的摘要算法,比如SHA1、SHA512猾愿、MD5等鹦聪。
    //sha256加密(Hmac方式)擁有一個加密Key,這樣更安全一些
    const secret="AK41abud";//秘鑰
    var hmac=crypto.createHmac("sha256",secret);
    var content=hmac.update("加密內(nèi)容ABCD1234");
    var cryptoContent=content.digest("hex");
    console.log("sha256(Hmac方式)加密后結(jié)果:%s",cryptoContent);

    log輸出:sha256(Hmac方式)加密后結(jié)果:b4e164a61eb1d0dd532988fe5448d47d65f1ee4d6caf6132200727d1d81dddc4

3.內(nèi)容加密解密類又分為: 對稱加密解密(AES)蒂秘,非對稱加密解密(RSA)

對信息進行加密解密泽本,有很多種算法,當然不只是AES和RSA這兩種姻僧,這兩種只是我們平時比較常用的规丽。
加密解密算法,大致又分為對稱加密和非對稱加密兩大類段化,當然這些加密算法都是可逆的嘁捷,如果像上面介紹的MD5、SHA1是不可逆的显熏,那我們把內(nèi)容加完秘后解不開了雄嚣,不就悲劇了。喘蟆。缓升。呵呵

  • AES對稱加密
    對稱加密大概可以理解為,加密和解密蕴轨,使用的是同一個秘鑰key港谊。
    //AES對稱加密
    var secretkey="passwd";//唯一(公共)秘鑰
    var content="需要加密的內(nèi)容ABC";
    var cipher=crypto.createCipher('aes192', secretkey);//使用aes192加密
    var enc=cipher.update(content,"utf8","hex");//編碼方式從utf-8轉(zhuǎn)為hex;
    enc+=cipher.final('hex');//編碼方式轉(zhuǎn)為hex;
    //
    //AES對稱解密
    var decipher=crypto.createDecipher('aes192', secretkey);
    var dec=decipher.update(enc,"hex", "utf8");
    dec+=decipher.final("utf8");
    console.log("AES對稱解密結(jié)果:"+dec);

    log輸出:AES對稱解密結(jié)果:需要加密的內(nèi)容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) => {
        // 注意嗤练,第二個參數(shù)是Buffer類型
        return crypto.publicEncrypt(key, Buffer.from(data));
    };
    // 解密方法
    var decrypt = (encrypted, key) => {
        // 注意,encrypted是Buffer類型
        return crypto.privateDecrypt(key, encrypted);
    };

    const plainText = "我是RSA非對稱加密字符串內(nèi)容";
    const crypted = encrypt(plainText, pubkey2); // 加密
    const decrypted = decrypt(crypted, prikey2); // 解密
    console.log("RSA非對稱解密結(jié)果:%s",decrypted.toString());

    log輸出:RSA非對稱解密結(jié)果:我是RSA非對稱加密字符串內(nèi)容

4.內(nèi)容簽名類(RSA+SHA1 或 RSA+SHA256 或 RSA+MD5等等)

“信息內(nèi)容簽名”其實和我們?nèi)粘V袑堎|(zhì)文件進行簽名是一個道理在讶。又稱為“數(shù)字簽名”煞抬,包括報文摘要。報文摘要和非對稱加密一起构哺,提供數(shù)字簽名的方法此疹。

數(shù)字簽名主要是保證信息的完整和提供信息發(fā)送者的身份認證和不可抵賴性,這其中,“完整性”主要就是由報文摘要提供的蝗碎,報文摘要就是用來防止發(fā)送的報文被篡改。

使用流程:

  • 使用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 = "我是信息內(nèi)容摘要"
    var sign = crypto.createSign('RSA-SHA256');//創(chuàng)建簽名算法
    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("非對稱簽名校驗結(jié)果結(jié)果:"+t);

    log輸出:非對稱簽名校驗結(jié)果結(jié)果:true

這里我把其它的公鑰和秘鑰對也貼出來,otherkeys.js內(nèi)容:

//其它私鑰和公鑰
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文檔。
簽名算法嫌蚤,我們在平時用的還是很多的辐益,比如 微信支付、支付寶支付等等脱吱,使用簽名需要去驗明信息來源身份的有效性智政,這樣使我們的信息傳遞交互更安全可靠!箱蝠!

謝謝大家续捂!共勉!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宦搬,一起剝皮案震驚了整個濱河市牙瓢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌床三,老刑警劉巖一罩,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撇簿,居然都是意外死亡聂渊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門四瘫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汉嗽,“玉大人,你說我怎么就攤上這事找蜜”睿” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弓叛。 經(jīng)常有香客問我彰居,道長,這世上最難降的妖魔是什么撰筷? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任陈惰,我火速辦了婚禮,結(jié)果婚禮上毕籽,老公的妹妹穿的比我還像新娘抬闯。我一直安慰自己,他們只是感情好关筒,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布溶握。 她就那樣靜靜地躺著,像睡著了一般蒸播。 火紅的嫁衣襯著肌膚如雪睡榆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天廉赔,我揣著相機與錄音肉微,去河邊找鬼。 笑死蜡塌,一個胖子當著我的面吹牛碉纳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播馏艾,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼劳曹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了琅摩?” 一聲冷哼從身側(cè)響起铁孵,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎房资,沒想到半個月后蜕劝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡轰异,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年岖沛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搭独。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡婴削,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出牙肝,到底是詐尸還是另有隱情唉俗,我是刑警寧澤嗤朴,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站虫溜,受9級特大地震影響雹姊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衡楞,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一容为、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寺酪,春花似錦、人聲如沸替劈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽陨献。三九已至盒犹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間眨业,已是汗流浹背急膀。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留龄捡,地道東北人卓嫂。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像聘殖,于是被迫代替她去往敵國和親晨雳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容