1. 程式人生 > 程式設計 >詳解使用Nodejs內建加密模組實現對等加密與解密

詳解使用Nodejs內建加密模組實現對等加密與解密

加密與解密是保證通訊安全的一種重要手段,現在加密演算法已經有很多,並且都有成熟的軟體包可以使用,這就大大降低了應用開發程式設計師的負擔,只需要使用這些第三方提供的加密解密庫就可以使程式設計客棧用了,在Node.js中其實提供了一個非常強大而且方便的加密與解密模組crypto,我們不需要使用第三方的NPM庫就能實現簡單的加密與解密功能,畢竟使用加密與解密的目的就是為了保證通訊的安全,而使用非官方的第三方庫總是有可能存在新增的後門或者什麼的,而使用Node.js自帶的crypto模組就能最大程度的保證加密的安全性。

雜湊值計算 crypto.Hash

雜湊值計算通常是用來對資料完整性和正確性做一個校驗目的使用,當我們需要確保接受的資料是跟傳送的資料一毛一樣的時候,就可以通過分別計算髮送資料的雜湊值和接收到資料的雜湊值。做一個簡單的比較就能判斷出來,兩個一樣的資料得到的雜湊值肯定是一樣的。雜湊值不能逆向計算還原成原來的資料,所以只能用來驗證資料。那麼在Node.js中該如何使用呢?

示例程式碼

const crypto = require('crypto');
const hash = crypto.createHash('sha256');

hash.update('some data to hash');
console.log(hash.digest('hex'));
// Prints:
//   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50

上面的程式碼是抄錄自Node.js官方演示程式碼,我選擇了其中最簡單的使用方式,這種使用方式也是我們最常使用的,那就是對一個字串或者一組資料進行雜湊值計算。crypto.Hash實現的雜湊演算法是使用固定的祕語Secret作為計算的運算元,Node.js中還有一個與其類似的,但是可以改變祕語Secret的加密類crypto.Hmac。

可變雜湊計算 crypto.Hmac

示例程式碼

const crypto = require('crypto');
const hmac = crypto.createHmac('sha256','a secret');

hmac.update('some data to hash');
console.log(hmac.digest('hex'));
// Prints:
//   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e

crypto.Hmac的使用方法與crypto.Hash很相似,唯一不同點就是多了一個可以自定義的祕語Secret,使用定製的祕語Secret的一個用途就是儲存密碼的時候可以提高安全性,畢竟使用預設祕語Secret的雜湊演算法函式,只要知道使用了什麼演算法就能通過暴力碰撞獲取到密碼,但是使用了定製祕語Secret的雜湊函式,就算是使用窮舉法也幾乎是不可能破解的。

對稱加密與解密

對稱加密與解密的意思是加密與解密雙方使用同一個祕語Secret實現加解密演算法運算,這種加密演算法不需要什麼公鑰和私鑰,使用起來比較方便,而且與雜湊演算法不同,對稱加密解密是可以雙向互逆運算的。

Node.js中支援許多對稱加密演算法,不過到底有哪些加密演算法是取決於你計算機中安裝的OpenSSL決定的,Node.js只是去呼叫了OpenSSL。這就給我們帶來一個麻煩,那就是沒有辦法在文件中查詢加密演算法資訊,這個之後就會知道麻煩在哪裡。

對稱加密使用過程

加密示例程式碼

 const crypto = require('crypto');

 const algorithm = 'aes-192-cbc';
 const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
 const key = crypto.scryptSync(password,'salt',24);
// Use `crypto.randomBytes` to generate a random iv instead of the static iv
// shown here.
 const iv = Buffer.alloc(16,0); // Initialization vector.

 const cipher = crypto.createCipheriv(algorithm,key,iv);

 let encrypted = cipher.update('some clear text data','utf8','hex');
 encrypted += cipher.final('hex');
 console.log(encrypted);
// Prints: e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa

讓我們一步一步的來解釋這個程式碼吧。

const algorithm = 'aes-192-cbc';

這一行是定義所使用的加密演算法,通常有3個部分組成,中間用-連線,第一部分是加密演算法名稱aes,第二部分是加密長度192位,第三部分是加密認證方法(這部分可能理解有誤)cbc

 const key = crypto.scryptSync(password,24);

這一行是生成金鑰Key,注意最後的數字24,這個是生成的金鑰Key長度,最小是8,最大沒限制不過必須是8的倍數才行,金鑰Key的長度是跟所用的加密演算法相關的,因為文件中沒有這部分資訊,所以使用的時候只能不斷的嘗試,否則就會報錯!

 const iv = Buffer.alloc(16程式設計客棧,0); // Initialization vector.
 const cipher = crypto.createCipheriv(algorithm,iv);

第6行是建立初始向量Initialization vector,這也是一個非常關鍵但是文件中沒有說明的地方,IV的長度也很關鍵,目前只知道長度必須是8的倍數,而且長度是跟所使用的演算法位數是相關的,程式設計客棧但是文件中沒有地方明確說明,所以使用的時候也只能是不斷嘗試。

金鑰Key和初始向量Initialization vector這兩個關鍵引數的長度沒有在Node.js文件中寫明確是非常遺憾的,導致我們使用的時候要麼去查加密演算法相關資料,要麼只能一個一個手動嘗試,非常的不方便。

 let encrypted = cipher.update('some clear text data','hex');
 encrypted += cipher.final('hex');

這兩行就很簡單了,就是對輸入的字串進行加密計算,update(...,'hex')中utf8是加密前字串的編碼格式,hex是加密後輸出的編碼格式。最後需要在加密後的字串後面新增一個結束字元,這個工作由final('hex')完成,hex也是輸出的字元編碼格式。

對稱解密過程

解密示例程式碼

const crypto = require('crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = crypto.scryptSync(password,24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16,0); // Initialization vector.

const decipher = crypto.createDecipheriv程式設計客棧(algorithm,iv);

// 上面是加密部分
// 因為加密和解密的金鑰和初始向量要一致
// 所以就把加密和解密合並書寫

// Encrypted using same algorithm,key and iv.
const encrypted =
  'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
let decrypted = decipher.update(encrypted,'hex','utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data

解密就是加密的逆過程,注意點也是一樣的,就是金鑰Key和初始向量Initialization vector這兩個引數的長度,還有一點要要注意的是decipher.update輸入的第一個引數只能是字串,不能是Buff程式設計客棧er型別,個人感覺用Buffer效能應該會更好點,可能以後會增加這個型別支援吧。

結語

到此這篇關於詳解使用Nodejs內建加密模組實現對等加密與解密的文章就介紹到這了,更多相關Nodejs對等加密與解密內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!