加密這方面nodejs自帶原生的crypto模塊,在網關開發中或多或少會牽涉到這塊,大部分集中在des-ecb
、aes
的加密上,所以咱們封裝了這麼一個工具庫用來平時的加密和解密使用,傳送門。html
在使用這些api以前,咱們來熟悉熟悉一下crypto模塊,以及瞭解加密和解密的一些基本知識。node
nodejs提供了衆多和加密解密相關的封裝器,好比OpenSSL的hash、HMAC(哈希信息驗證碼)、cipher(加密)、decipher(解密)、sign(簽名)和校驗函數。如今咱們簡單地學習一下這些對應的概念。git
所謂的SPKAC是由網景公司原始實現的一種CSR(Certificate Signing Request/證書註冊請求)機制。crypto模塊提供Certificate
類來處理SPKAC數據。Nodejs內部使用的是OpenSSL's SPKAC實現方式。github
Cipher
類實例用來加密數據。使用方式以下兩種,任選其一便可:算法
cipher.update
和cipher.final
方法來產生加密的數據所謂的Cipher是加密的意思,天然就有加密的算法了,自己密碼學就是一門複雜的學科,這裏咱們只會挑選幾個比較經常使用的加密算法來簡單解釋。typescript
首先咱們能夠查看nodejs支持的加密算法有哪些?由於nodejs內部是有使用到openssl,因此也能夠經過電腦自帶的openssl命令openssl list-cipher-algorithms
獲取,也可使用下面的方式獲取:api
const crypto = require('crypto')
crypto.getCiphers()
複製代碼
獲得一個比較大的數組,都列舉不完了:數組
[ 'aes-128-cbc',
'aes-128-cbc-hmac-sha1',
'aes-128-cbc-hmac-sha256',
'aes-128-ccm',
'aes-128-cfb',
'aes-128-cfb1',
'aes-128-cfb8',
'aes-128-ctr',
'aes-128-ecb',
'aes-128-gcm',
'aes-128-ocb',
'aes-128-ofb',
'aes-128-xts',
'aes-192-cbc',
'aes-192-ccm',
'aes-192-cfb',
'aes-192-cfb1',
'aes-192-cfb8',
'aes-192-ctr',
'aes-192-ecb',
'aes-192-gcm',
'aes-192-ocb',
'aes-192-ofb',
'aes-256-cbc',
'aes-256-cbc-hmac-sha1',
'aes-256-cbc-hmac-sha256',
'aes-256-ccm',
'aes-256-cfb',
'aes-256-cfb1',
'aes-256-cfb8',
'aes-256-ctr',
'aes-256-ecb',
'aes-256-gcm',
'aes-256-ocb',
'aes-256-ofb',
'aes-256-xts',
'aes128',
'aes128-wrap',
'aes192',
'aes192-wrap',
'aes256',
'aes256-wrap',
'bf',
'bf-cbc',
'bf-cfb',
'bf-ecb',
'bf-ofb',
'blowfish',
...
'des',
'des-cbc',
'des-cfb',
'des-cfb1',
'des-cfb8',
'des-ecb',
...
'des3',
... 39 more items ]
複製代碼
咱們挑選AES加密算法和DES加密算法來講說幾個基本的加密概念安全
高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。通過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日發佈於FIPS PUB 197,並在2002年5月26日成爲有效的標準。2006年,高級加密標準已然成爲對稱密鑰加密中最流行的算法之一。bash
AES使用的祕鑰長度能夠128位、192位或256位,因此你看到的加密算法:aes-128/196/256,表示的都是祕鑰的位數。而最後的一段是AES的工做模式,最經常使用的工做模式是ECB、CBC、CFB和OFB四種。
des對稱加密,是一種比較傳統的加密方式,其加密運算、解密運算使用的是一樣的密鑰,信息的發送者和信息的接收者在進行信息的傳輸與處理時,必須共同持有該密碼(稱爲對稱密碼),是一種對稱加密算法。
DES使用一個56位的密鑰以及附加的8位奇偶校驗位,產生最大64位的分組大小。因此正常咱們給DES加密的時候都是傳遞56位祕鑰便可。一樣DES也有幾種工做模式:DES、ECB、CBC,工做模式基本和上面的一致。
nodejs使用crypto.createCipheriv()
來建立加密實例,該函數的接受三個參數:algorithm、key、initialization vector(iv)。
那麼問題來了,什麼是初始化向量?何時須要使用到?
根據wiki的解釋:
在密碼學中,初始化向量(IV)或者起始變量(SV)是一段固定大小的到密碼原語的輸入,該原語一般要求是隨機或僞隨機的。隨機化對於加密方案實現語義安全性相當重要,這種特性使得在相同密鑰下重複使用該方案不容許攻擊者推斷加密消息片斷之間的關係。對於分組密碼,IV的使用由操做模式來描述。其餘原語也須要隨機化,例如通用哈希函數和基於此的消息身份驗證代碼。
複製代碼
一句話歸納就是:爲了保證每條消息的惟一性,須要使用初始化向量IV。
在上述的四種工做模式中,除了ECB不須要用到初始化向量,其餘三種都須要用到IV。咱們可使用該方法生成IV: Crypto.randomBytes(16)
建立加密實例後,有可能會用到這個方法:setAutoPadding
,那麼爲何咱們會須要padding呢?
首先咱們先了解該方法的做用:當使用塊加密算法的時候,Cipher類會自動地添加padding到輸入塊中達到合適的塊大小。當咱們調用該函數禁用掉這個的時候,整個輸入塊的長度必須爲cipher塊尺寸的整數倍,不然調用cipher.final的時候是會報錯的。
接着回答剛纔的問題:
因爲被加密數據分組時,有可能不會正好爲128bit的整數倍,因此須要padding(填充補齊),填充的模式有如下幾種:
這裏還有一個問題是:Nodejs如何決定咱們的padding使用的是哪一種呢?這個問題待解!
另一個問題是,調用完cipher.update
以後還得調用一個cipher.final
,這是爲啥呢?由於final的做用是收尾,由於update以後會有一些剩餘沒有加密的數據,只有調用了這個纔算是對整個數據源進行加密,所以咱們看到代碼都是兩者的結果的一個拼接。
Decipher類的實例用於解密數據。和Cipher同樣的使用方法。就再也不贅述了
DiffieHellman類是一個用來建立Diffie-Hellman鍵交換的工具。什麼叫作Diffie-Hellman?Diffie-Hellman算法是第一個公開密鑰算法,早在 1976 年就發現了。其安全性源於在有限域上計算離散對數,比計算指數更爲困難。該算法可使兩個用戶之間安全地交換一個密鑰,但不能用於加密或解密信息。具體實現原理不贅述。
ECDH類是建立橢圓曲線Diffie-Hellman(Elliptic Curve Diffie-Hellman (ECDH))鍵交換的實用工具。ECDH是基於ECC(Elliptic Curve Cryptosystems,橢圓曲線密碼體制,參看ECC)的DH( Diffie-Hellman)密鑰交換算法。交換雙方能夠在不共享任何祕密的狀況下協商出一個密鑰。
ECC是創建在基於橢圓曲線的離散對數問題上的密碼體制,給定橢圓曲線上的一個點P,一個整數k,求解Q=kP很容易;給定一個點P、Q,知道Q=kP,求整數k確是一個難題。ECDH即創建在此數學難題之上。
Hash類是用於建立數據哈希值的工具類。使用方式以下兩種,任選其一便可:
hash.update
和hash.final
方法來產生加密的數據Hmac類是用於建立加密Hmac摘要的工具。HMAC是密鑰相關的哈希運算消息認證碼(Hash-based Message Authentication Code),HMAC運算利用哈希算法,以一個密鑰和一個消息爲輸入,生成一個消息摘要做爲輸出。
Sign類是用於生成簽名的實用工具。使用方式以下兩種,任選其一便可:
sign.update
和sign.sign
方法來產生加密的數據Verify類是驗證簽名的工具。使用方式以下兩種,任選其一便可:
verify.update
和verify.verify
的方法來驗證簽名基於上面的一些基本知識,咱們在Nodejs的基礎上封裝了這麼一個基本的工具庫,供平時咱們開始中使用,鑑於還有好多在平時中沒有用到,這裏先提供簡單的一些封裝,等後續有用到的時候在上面繼續完善。
整個工具庫根據crypto的功能分爲如下文件:
├── test 單元測試文件
├── types typescript類型文件
├── lib
│ ├── cipher 封裝了加密解密相關的方法類
│ ├── certificate 封裝了證書相關的方法類
│ ├── diffieHellman 封裝了Diffie-Hellman相關的方法類
│ ├── ecdh 封裝了橢圓曲線Diffie-Hellman相關的方法類
│ ├── hash 封裝了哈希相關的方法類
│ ├── hmac 封裝了Hmac摘要相關的方法類
│ ├── sign 封裝了簽名相關的方法類
│ └── verify 封裝了簽名驗證相關的方法類
複製代碼
後續慢慢完善這個工具庫。傳送門