Node之加密與解密處理

### crypto模塊概述

在Node.js中,使用OpenSSL類庫(kù)作為其內(nèi)部實(shí)現(xiàn)加密與解密處理的基礎(chǔ)手段,這是因?yàn)槟壳癘penSSL已經(jīng)成為了一個(gè)經(jīng)過(guò)嚴(yán)格測(cè)試的可靠的加密與解密算法的實(shí)現(xiàn)工具。

在Node.js中,OpenSSL類庫(kù)被封裝在crypto模塊中,因此開(kāi)發(fā)者可以使用crypto模塊來(lái)實(shí)現(xiàn)各種不同的加密與解密處理。例如,crypto模塊中包含了類似MD5或SHA-1之類的散列算法。開(kāi)發(fā)者也可以通過(guò)crypto模塊來(lái)實(shí)現(xiàn)HMAC運(yùn)算 [1]。在crypto模塊中,提供了一些加密方法來(lái)實(shí)現(xiàn)數(shù)據(jù)的可靠加密。另外,在crypto模塊中,也提供了一些利用HMAC運(yùn)算來(lái)實(shí)現(xiàn)數(shù)字簽名以及對(duì)數(shù)字簽名進(jìn)行驗(yàn)證的方

法。

### 查看Node.js中能夠使用的所有加密算法

在crypto模塊中,為每一種加密算法定義了一個(gè)類??梢允褂胓etCiphers方法

來(lái)查看Node.js中能夠使用的所有加密算法。

```

crypto.getCiphers()

```

### 查看Node.js中能夠使用的所有散列算法

可以使用getHashes方法來(lái)查看在Node.js中能夠使用的所有散列算法。

```

crypto.getHashes()

```

### 散列算法

散列(哈希)算法用來(lái)實(shí)現(xiàn)一些重要處理,例如,在允許對(duì)一段數(shù)據(jù)進(jìn)行驗(yàn)證的前提下,將數(shù)據(jù)進(jìn)行模糊化,或者為一大段數(shù)據(jù)提供一個(gè)驗(yàn)證碼

在node中,為了使用散列算法,首先應(yīng)該使用createHash方法創(chuàng)建一個(gè)hash對(duì)象。

```

let hash=crypto.createHash(algorithm)

```

- algorithm:參數(shù)值為一個(gè)在Node.js中可以使用的算法,如'sha1'、'md5'、'sha256'、'sha512'和'ripemd160'等,用于指定需要使用的散列算法,該方法返回被創(chuàng)建的hash對(duì)象

在創(chuàng)建一個(gè)hash對(duì)象后可以通過(guò)使用該對(duì)象的update方法創(chuàng)建一個(gè)摘要。該方法的使用方式如下所示

```

hash.update(data,[input_encoding])

```

- data:參數(shù)值為一個(gè)Buffer對(duì)象或一個(gè)字符串,用于指定摘要內(nèi)容

- input_encoding:用于指定摘要內(nèi)容所需使用的編碼格式,可指定參數(shù)值為“utf8”、“ascii”或“binary”。如果不使用input_encoding參數(shù),則data參數(shù)值必須為一個(gè)Buffer對(duì)象。可以在摘要被輸出前使用多次update方法來(lái)添加摘要內(nèi)容。

#### 輸出摘要內(nèi)容

可以使用hash對(duì)象的digest方法來(lái)輸出摘要內(nèi)容。在使用了hash對(duì)象的digest方法后,不能再向hash對(duì)象中追加摘要內(nèi)容。

```

hash.digest([encoding])

```

在hash對(duì)象的digest方法中,使用一個(gè)可選參數(shù),參數(shù)值為一個(gè)字符串,用于指定輸出摘要的編碼格式,可指定參數(shù)值為“hex”、“binary”及“base64”。如果使用了該參數(shù),那么digest方法返回字符串格式的摘要內(nèi)容,如果不使用該參數(shù),那么digest方法返回一個(gè)Buffer對(duì)象。在hash對(duì)象的digest方法被調(diào)用之后,該對(duì)象不能再被使用。

#### 散列算法完整使用示例

```

var crypto = require('crypto');

var fs = require('fs');

var shasum = crypto.createHash('sha1');

var s = fs.ReadStream('./app.js');

s.on('data', function(d) {

? ? shasum.update(d);

});

s.on('end', function() {

? ? var d = shasum.digest('hex');

? ? console.log(d);

});

```

### HMAC算法

HMAC算法將散列算法與一個(gè)密鑰結(jié)合在一起,以阻止對(duì)簽名完整性的破壞。在Node.js中,為了使用HMAC算法,首先應(yīng)該使用createHmac方法創(chuàng)建一個(gè)hmac對(duì)象。

```

crypto.createHmac(algorithm,key)

```

- algorithm:為一個(gè)在Node.js中可以使用的算法,例如'sha1'、'md5'、'sha256'、'sha512'和'ripemd160'等,用于指定我們所需要使用的散列算法。該方法返回被創(chuàng)建的hmac對(duì)象。

- key:參數(shù)值為一個(gè)字符串,用于指定一個(gè)PEM格式的密鑰。

#### 創(chuàng)建一個(gè)摘要

在hmac對(duì)象的update方法中,使用一個(gè)參數(shù),其參數(shù)值為一個(gè)Buffer對(duì)象或一個(gè)字符串,用于指定摘要內(nèi)容??梢栽谡惠敵銮笆褂枚啻蝩pdate方法來(lái)添加摘要內(nèi)容。

```

hmac.update(data)

```

#### 輸出摘要

可以使用hmac對(duì)象的digest方法輸出摘要內(nèi)容。在使用了hmac對(duì)象的digest方法后,不能再向hmac對(duì)象中追加摘要內(nèi)容。

```

hmac.digest([encoding])

```

#### HMAC算法的使用示例

```

var crypto = require('crypto');

var fs = require('fs');

var pem = fs.readFileSync('key.pem');

var key = pem.toString('ascii');

var shasum = crypto.createHmac('sha1',key);

var s = fs.ReadStream('./app.js');

s.on('data', function(d) {

? ? shasum.update(d);

});

s.on('end', function() {

? ? var d = shasum.digest('hex');

? ? console.log(d);

});

```

### 公鑰加密

#### 加密數(shù)據(jù)

在crypto模塊中,Cipher類用于對(duì)數(shù)據(jù)進(jìn)行加密操作。在加密數(shù)據(jù)之前,首先需要?jiǎng)?chuàng)建一個(gè)cipher對(duì)象??梢酝ㄟ^(guò)如下所示的兩種方法創(chuàng)建cipher對(duì)象。

1.createCipher方法:該方法使用指定的算法與密碼來(lái)創(chuàng)建cipher對(duì)象。

```

crypto.createCipher(algorithm,password)

```

- algorithm:用于指定在加密數(shù)據(jù)時(shí)所使用的算法,例如“blowfish'”、“aes-256-cbc”等。

- password:用于指定加密時(shí)所使用的密碼,參數(shù)值必須為一個(gè)二進(jìn)制格式的字符串或一個(gè)Buffer對(duì)象。

2.createCipheriv方法:該方法使用指定的算法、密碼與初始向量(Initialization Vector,IV)來(lái)創(chuàng)建cipher對(duì)象。該方法的使用方式如下:

```

crypto.createCipheriv(algorithm,password,iv)

```

- algorithm:用于指定在加密數(shù)據(jù)時(shí)所使用的算法,例如“blowfish'”、“aes-256-cbc”等。

- password:用于指定加密時(shí)所使用的密碼,參數(shù)值必須為一個(gè)二進(jìn)制格式的字符串或一個(gè)Buffer對(duì)象。

- iv:用于指定加密時(shí)所使用的初始向量,參數(shù)值必須為一個(gè)二進(jìn)制格式的字符串或一個(gè)Buffer對(duì)象。

#### 指定需要被加密的數(shù)據(jù)。

在創(chuàng)建了一個(gè)cipher對(duì)象后,可以通過(guò)使用該對(duì)象的update方法來(lái)指定需要被加密的數(shù)據(jù)。

```

cipher.update(data,[input_encoding],[output_encoding])

```

- data:為必須使用的參數(shù),為一個(gè)Buffer對(duì)象或一個(gè)字符串,用于指定需要加密的數(shù)據(jù)

- input_encoding:用于指定被加密的數(shù)據(jù)所需使用的編碼格式,可指定參數(shù)值為“utf8”、“ascii”及“binary”。

- output_encoding:用于指定輸出加密數(shù)據(jù)時(shí)使用的編碼格式,可指定參數(shù)值為“hex”、“binary”或“base64”。

#### 返回加密數(shù)據(jù)。

可以使用cipher對(duì)象的final方法來(lái)返回加密數(shù)據(jù)。當(dāng)該方法被調(diào)用時(shí),任何cipher對(duì)象中所緩存的數(shù)據(jù)都將被加密,如果加密數(shù)據(jù)的字節(jié)數(shù)不足以創(chuàng)建一個(gè)塊,將使用PKCS填充方式來(lái)填充這個(gè)塊。在使用了cipher對(duì)象的final方法后,不能再向cipher對(duì)象中追加加密數(shù)據(jù)。

```

cipher.final([output_encoding])

```

- output_encoding:參數(shù)值為一個(gè)字符串,用于指定在輸出加密數(shù)據(jù)的編碼格式,可指定參數(shù)值為“hex”、“binary”及“base64”。如果使用了該參數(shù),那么final方法返回字符串格式的加密數(shù)據(jù),如果不使用該參數(shù),那么final方法返回一個(gè)Buffer對(duì)象。當(dāng)cipher對(duì)象的final方法被調(diào)用之后,該對(duì)象不能再被使用。

#### 使用cipher對(duì)象加密數(shù)據(jù)

```

var crypto = require('crypto');

var fs = require('fs');

var pem = fs.readFileSync('key.pem');

var key = pem.toString('ascii');

var cipher = crypto.createCipher('blowfish', key);

var text = "test";

cipher.update(text,'binary','hex');

var crypted=cipher.final('hex')

console.log(crypted);

```

### 解密數(shù)據(jù)

在crypto模塊中,Decipher類用于對(duì)加密后的數(shù)據(jù)進(jìn)行解密操作。在解密數(shù)據(jù)之前,首先需要?jiǎng)?chuàng)建一個(gè)decipher對(duì)象。可以通過(guò)如下所示的兩種方法創(chuàng)建decipher對(duì)象。

1.createDecipher方法:該方法使用指定的算法與密碼來(lái)創(chuàng)建decipher對(duì)象。

```

crypto.createDecipher(algorithm,password)

```

- algorithm:用于指定在解密數(shù)據(jù)時(shí)所使用的算法,例如“blowfish”、“aes-256-cbc”等,該算法必須與加密該數(shù)據(jù)時(shí)所使用的算法保持一致。

- password:用于指定解密時(shí)所使用的密碼,其參數(shù)值必須為一個(gè)二進(jìn)制格式的字符串或一個(gè)Buffer對(duì)象,該密碼必須與加

密該數(shù)據(jù)時(shí)所使用的密碼保持一致。

2.createDecipheriv方法:該方法使用指定的算法、密碼與初始向量來(lái)創(chuàng)建decipher對(duì)象。

```

crypto.createDecipheriv(algorithm,password,iv)

```

- algorithm:用于指定在解密數(shù)據(jù)時(shí)所使用的算法,例如“blowfish”、“aes-256-cbc”等,該算法必須與加密該數(shù)據(jù)時(shí)所使用的算法保持一致。

- password:用于指定解密時(shí)所使用的密碼,其參數(shù)值必須為一個(gè)二進(jìn)制格式的字符串或一個(gè)Buffer對(duì)象,該密碼必須與加

密該數(shù)據(jù)時(shí)所使用的密碼保持一致。

- iv:用于指定解密時(shí)所使用的初始向量,參數(shù)值必須為一個(gè)二進(jìn)制格式的字符串或一個(gè)Buffer對(duì)象,該初始向量必須與加密該數(shù)據(jù)時(shí)所使用的初始向量保持一致。

createDecipheriv方法返回一個(gè)被創(chuàng)建的decipher對(duì)象。

#### 數(shù)據(jù)解密

在創(chuàng)建了一個(gè)decipher對(duì)象之后,可以通過(guò)使用該對(duì)象的update方法來(lái)指定需要被解密的數(shù)據(jù)。

```

decipher.update(data,[input_encoding],[output_encoding])

```

#### 返回經(jīng)過(guò)解密之后的原始數(shù)據(jù)

```

decipher.final([output_encoding])

```

### 創(chuàng)建簽名

在網(wǎng)絡(luò)中,私鑰的擁有者可以在一段數(shù)據(jù)被發(fā)送之前先對(duì)該數(shù)據(jù)進(jìn)行簽名操作,在簽名的過(guò)程中,將對(duì)這段數(shù)據(jù)執(zhí)行加密處理。在經(jīng)過(guò)加密后的數(shù)據(jù)發(fā)送之后,數(shù)據(jù)的接收者可以通過(guò)公鑰的使用來(lái)對(duì)該簽名進(jìn)行解密及驗(yàn)證操作,以確保這段數(shù)據(jù)是私鑰的擁有者所發(fā)出的原始數(shù)據(jù),且在網(wǎng)絡(luò)的傳輸過(guò)程中未被修改。

在Node.js中,在進(jìn)行簽名操作之前,首先需要使用createSign方法創(chuàng)建一個(gè)sign對(duì)象

```

crypto.createSign(algorithm)

```

- algorithm:指定加密算法

createSign方法返回被創(chuàng)建的sign對(duì)象。

#### 指定加密數(shù)據(jù)

在創(chuàng)建了一個(gè)sign對(duì)象后,可以通過(guò)使用該對(duì)象的update方法來(lái)指定需要被加密的數(shù)據(jù)。

```

sign.update(data)

```

在sign對(duì)象的update方法中,使用一個(gè)參數(shù),其參數(shù)值為一個(gè)Buffer對(duì)象或一個(gè)字符串,用于指定需要被加密的數(shù)據(jù)??梢栽趯?duì)數(shù)據(jù)進(jìn)行簽名前使用多次update方法來(lái)添加數(shù)據(jù)。

#### 對(duì)數(shù)據(jù)進(jìn)行簽名

可以使用sign對(duì)象的sign方法對(duì)數(shù)據(jù)進(jìn)行簽名。在使用了sign對(duì)象的sign方法之后,不能再使用sign對(duì)象的update方法追加數(shù)據(jù)。

```

sign.sign(private_key,[output_format])

```

- private_key:為一個(gè)字符串,用于指定PEM格式的私鑰。

- output_format:用于指定簽名輸出時(shí)所使用的編碼格式,可指定參數(shù)值為“hex”、“binary”或“base64”。

### 簽名驗(yàn)證

在crypto模塊中,Verify類用于對(duì)簽名進(jìn)行驗(yàn)證操作。在對(duì)簽名進(jìn)行驗(yàn)證之前,首先需要?jiǎng)?chuàng)建一個(gè)verify對(duì)象,可以通過(guò)createVerify方法創(chuàng)建verify對(duì)象

```

crypto.createVerify(algorithm)

```

- algorithm:用于指定在驗(yàn)證簽名數(shù)據(jù)時(shí)所使用的算法

createVerify方法返回一個(gè)被創(chuàng)建的verify對(duì)象。

#### 指定需要被驗(yàn)證的數(shù)據(jù)

```

verify.update(data)

```

可以使用verify對(duì)象的verify方法來(lái)對(duì)簽名進(jìn)行驗(yàn)證。

```

verify.verify(object,signature,[signature_format])

```

- object:用于指定驗(yàn)證時(shí)所使用的對(duì)象,參數(shù)值為一個(gè)字符串,該字符串值可以為一個(gè)RSA公鑰、一個(gè)DSA公鑰或一個(gè)X.509證書(shū)。

- signature:必須為sign對(duì)象,用于指定被驗(yàn)證的簽名。

- signature_format:用于指定在生成該簽名時(shí)所使用的編碼格式,可指定參數(shù)值為“hex”、“binary”及“base64”。

#### 使用verify對(duì)象對(duì)簽名進(jìn)行驗(yàn)證

```

var crypto = require('crypto');

var fs = require('fs');

var privatePem = fs.readFileSync('key.pem');

var publicPem = fs.readFileSync('cert.pem');

var key = privatePem.toString();

var pubkey = publicPem.toString();

var data = "test"

var sign = crypto.createSign('RSA-SHA256');

sign.update(data);

var sig = sign.sign(key, 'hex');

var verify = crypto.createVerify('RSA-SHA256');

verify.update(data);

console.log(verify.verify(pubkey, sig, 'hex'));

```

### 壓縮與解壓縮處理

在Node.js中,可以使用zlib模塊進(jìn)行壓縮及解壓縮處理,在該模塊內(nèi)部使用zlib類庫(kù)實(shí)現(xiàn)這些處理。具體不做描述,可見(jiàn)node官方文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在最近的每日讀詩(shī)中很喜歡這首: 生活 - 薩羅基妮·奈杜 孩子,你還沒(méi)體驗(yàn)過(guò)人生,盡管它看起來(lái) 是夢(mèng)中可愛(ài)的鐘乳石...
    回歸自己的成長(zhǎng)閱讀 171評(píng)論 0 1
  • “你知道我為什么堅(jiān)持跑步嗎?因?yàn)槲蚁M浇Y(jié)婚那天能有一個(gè)很好的身材,在場(chǎng)所有的女賓都羨慕你”
    Kukuxixi閱讀 200評(píng)論 0 0
  • 在硬筆書(shū)法愛(ài)好者中,流傳著一本"武功秘籍",雖只是一九八六年《中國(guó)鋼筆書(shū)法》雜志的增刊,卻被太多人收藏。 ...
    自在天狐閱讀 593評(píng)論 0 4
  • 宋子韻聽(tīng)完也很無(wú)奈,她看著熾游,沒(méi)有說(shuō)話,二人又相互天談了些,睡了,最后的一個(gè)安穩(wěn)的睡眠了。 第二日,宋府張燈...
    Satan小單閱讀 383評(píng)論 1 1
  • 莫拉是個(gè)精力特別充沛的小獅子。 別看它個(gè)頭小,腦子卻大的像一艘輪船。 她腦子里的問(wèn)題,就像船錨上的鎖鏈,那么多那么...
    一棵會(huì)行走的樹(shù)閱讀 633評(píng)論 0 0

友情鏈接更多精彩內(nèi)容