node中的crypto模塊操作方法
node中的crypto模塊指南
加密操作可能很棘手,以至于付費的加密服務公司的存在只是為了確保在代碼庫中正確實現(xiàn)加密操作。好消息是,只需學習一些知識,我們就可以使用 Node
的內置加密模塊免費進行適當?shù)募用堋?/p>
在本指南中,我們將探討如何使用 Node
的內置加密模塊正確執(zhí)行(對稱)加密/解密操作,以保護應用程序的數(shù)據(jù)。
首先,我們需要了解對稱加密的概念。
對稱加密
當人們談論“加密”時,他們往往指的是對稱加密,這對于將文本加密為隨機字符串非常有用。與此相關的一個常見場景是對服務器上的用戶數(shù)據(jù)進行加密,以便將其“靜態(tài)加密”存儲在數(shù)據(jù)庫中。
通俗地說,對稱加密就是獲取要加密的文本(稱為明文),并使用帶有加密算法的密鑰來輸出加密文本(稱為密文)。該操作是可逆的,因此解密是我們可以使用與明文相同的密鑰。
看起來很容易吧?
但是當真正需要實現(xiàn)對稱加密時,開發(fā)人員經常會犯錯誤,因為有很多東西需要理解:
- 編碼格式:數(shù)據(jù)可以通過多種方式進行編碼/解碼,例如
base64
、hex
等。當從一種格式轉換為另一種格式時,這些不同的表示方式常常使開發(fā)人員感到困惑。算法和配置:有許多加密算法需要考慮,例如aes-256-gcm
或aes-256-cbc
,每種算法都有自己的要求。 - 隨機性:加密過程中使用的密鑰應隨機生成,以確保高熵。很多時候,開發(fā)人員認為他們正在生成足夠隨機的密鑰,但事實并非如此。
- 復雜性:
Node.js
中的加密涉及幾個步驟,這些步驟對開發(fā)人員來說并不總是直觀的,而且有些概念一開始確實令人費解。以初始化向量(IV
)的概念為例;剛接觸密碼學的開發(fā)人員經常在加密過程中重復使用這些內容,這是一個很大的禁忌。
無論如何,在本文中并不會討論上述細微差別,但更多地關注我們如何通過示例使用 Node.js
正確執(zhí)行加密。
解釋如何正確執(zhí)行加密的最佳方法是演示使用aes-256-gcm
算法的正確實現(xiàn)。讓我們從加密開始。
加密
const crypto = require('crypto'); const encryptSymmetric = (key, plaintext) => { const iv = crypto.randomBytes(12).toString('base64'); const cipher = crypto.createCipheriv( "aes-256-gcm", Buffer.from(key, 'base64'), Buffer.from(iv, 'base64') ); let ciphertext = cipher.update(plaintext, 'utf8', 'base64'); ciphertext += cipher.final('base64'); const tag = cipher.getAuthTag() return { ciphertext, tag } } const plaintext = "encrypt me"; const key = crypto.randomBytes(32).toString('base64'); const { ciphertext, iv, tag } = encryptSymmetric(key, plaintext);
要執(zhí)行加密,我們需要兩項:
plaintext
:要加密的文本。key
:256 位加密密鑰。
我們從加密中得到以下輸出:
ciphertext
:加密文本。iv
:一個 96 位初始化向量,用于提供加密的初始狀態(tài),并允許在未來的加密操作中以不同iv
重復使用相同key
。tag
:在加密過程中生成的一段數(shù)據(jù),用于幫助驗證加密文本在稍后的解密過程中沒有被篡改。
讓我們看一下代碼:
const plaintext = "encrypt me"; const key = crypto.randomBytes(32).toString('base64');
這里我們定義執(zhí)行加密所需的輸入變量。除了要加密的文本之外,生成隨機數(shù)以通過更高的熵key
確保安全性也很重要;我更喜歡使用內置crypto.randomBytes()
來生成。我還將所有內容轉換為base64
格式,因為它在概念上易于存儲。
接下來我們來剖析一下加密函數(shù):
const encryptSymmetric = (key, plaintext) => { // 創(chuàng)建隨機初始化向量 const iv = crypto.randomBytes(12).toString('base64'); // 創(chuàng)建一個密碼對象 const cipher = crypto.createCipheriv("aes-256-gcm", key, iv); // 使用明文更新 cipher 對象以進行加密 let ciphertext = cipher.update(plaintext, 'utf8', 'base64'); // 完成加密過程 ciphertext += cipher.final('base64'); // 檢索加密的身份驗證標簽 const tag = cipher.getAuthTag(); return { ciphertext, iv, tag }; }
在這里,加密函數(shù)在使用aes-256-gcm
(可以將其視為一種加密算法)算法、key
和iv``crypto.createCipheriv
初始化期間創(chuàng)建一個新的密碼。下一部分加載要加密的文本plaintext
并執(zhí)行加密并檢索身份驗證標記,可以使用該標記來檢查ciphertext
解密過程中文本未被篡改。
關于加密,我們應該了解的最后一件事是如何處理數(shù)據(jù)。在加密用戶數(shù)據(jù)并靜態(tài)存儲它的情況下,需要將加密的數(shù)據(jù)ciphertext
、iv
、 和tag
存儲在數(shù)據(jù)庫中,并將密鑰安全地存儲在其他地方,例如服務器上的環(huán)境變量。當我們想要檢索數(shù)據(jù)時,可以從數(shù)據(jù)庫中查詢并使用密鑰對其進行解密。
說到這里,讓我們深入解密。
解密
const decryptSymmetric = (key, ciphertext, iv, tag) => { const decipher = crypto.createDecipheriv( "aes-256-gcm", Buffer.from(key, 'base64'), Buffer.from(iv, 'base64') ); decipher.setAuthTag(Buffer.from(tag, 'base64')); let plaintext = decipher.update(ciphertext, 'base64', 'utf8'); plaintext += decipher.final('utf8'); return plaintext; } const plaintext = decryptSymmetric(key, ciphertext, iv, tag);
要執(zhí)行解密,我們需要四項:
key
:用于加密原始文本的256位加密密鑰。ciphertext
:要解密的密文。iv
:加密期間使用的 96 位初始化向量。t
ag
:加密時生成的標簽。
我們從加密中得到以下輸出:
plaintext
:我們加密的原始文本。
讓我們看一下解密函數(shù):
const decryptSymmetric = (key, ciphertext, iv, tag) => { // 創(chuàng)建一個解密對象 const decipher = crypto.createDecipheriv( "aes-256-gcm", Buffer.from(key, 'base64'), Buffer.from(iv, 'base64') ); // 設置解密對象 decipher 的認證標簽 decipher.setAuthTag(Buffer.from(tag, 'base64')); // 使用 Base64 編碼的密文更新解密對象 let plaintext = decipher.update(ciphertext, 'base64', 'utf8'); // 完成解密 plaintext += decipher.final('utf8'); return plaintext; }
這里,解密函數(shù)在用aes-256-gcm
算法進行crypto.createDecipheriv
初始化時創(chuàng)建了一個解密對象,key
、iv
是之前創(chuàng)建的。接下來設置身份驗證標簽,用于檢查是否被ciphertext
篡改,最后我們執(zhí)行解密以獲得原始文本。
最后,我們的數(shù)據(jù)的安全程度取決于用于加密數(shù)據(jù)的密鑰。因此,強烈建議安全地存儲加密密鑰,并在應用程序中將它們作為環(huán)境變量進行訪問。
到此這篇關于node中的crypto模塊指南的文章就介紹到這了,更多相關node crypto模塊內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
10個Node.js庫幫助你優(yōu)化代碼和簡化開發(fā)
這篇文章主要介紹了10個Node.js庫幫助你優(yōu)化代碼和簡化開發(fā),其中包括處理數(shù)組、對象、字符串庫Lodash,緩存數(shù)據(jù)處理庫Node-cache,解析、操作和格式化日期和時間庫Moment.js,Redis操作庫,發(fā)送電子郵件庫Nodemailer2023-05-05node.js使用express-jwt報錯:expressJWT?is?not?a?function解決
這篇文章主要給大家介紹了關于node.js使用express-jwt報錯:expressJWT?is?not?a?function解決的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2023-03-03