當前位置:
首頁 > 最新 > 一種保護雲中的密碼的加密方法

一種保護雲中的密碼的加密方法

在本文中,後端開發人員可以了解為什麼使用加密很重要,以及如何有效地使用它來保護雲上的用戶信息(特別是密碼),使得數據即使泄露也不會在數十年內被破解。安全性是雲中的一個非常重要的主題,它對全棧開發至關重要,而且在所有產品和服務上都不可或缺。

我們首先會列出一些在開發中考慮安全性時要執行(或不執行)的簡單事務:

始終選擇使用經過其他人仔細檢查和審核的非本人的哈希/加密庫。

不要將密碼輸出到日誌中!

使用某種形式的密鑰管理服務。

不要將密鑰(API 密鑰、密碼)提交到代碼存儲庫中。

在本文中,我將通過一個示例應用程序來重點介紹加密關鍵數據的方式。對於本文中涉及的密碼存儲,我們將使用一個 SQLite 資料庫,因為它幾乎可以在任何系統上輕鬆使用。幾乎所有地方都使用著相同的原則和理念,而且資料庫系統應該無關緊要(但根據所選的資料庫,可能存在對用戶信息執行哈希運算和保護的更好方法)。我還想展示,如果您丟失了資料庫文件,但仍保持用戶哈希值完整且無法破解,結果會怎樣?

使用 bcrypt

bcrypt 是目前對密碼執行哈希運算的最廣泛使用的函數之一。它適用於大部分編程語言,而且通常有一些可用於特定框架和資料庫的非常特殊的模塊。讓我們看看這個存儲庫示例。此代碼通常與 Node.js 一起使用,而且非常簡單(它允許採用 sync 或 async 的方式來調用加鹽和哈希函數)。它還使您無需擔心實現細節和加鹽過程,使您能專註於防止意外的密碼泄露。

哈希運算、鹽和加密是什麼?

儘管哈希運算和加密看起來可能沒什麼不同,而且可以互換使用,但它們實際上有很大區別,而且有不同的用例。哈希函數接受一些輸入,並對輸出進行單向映射。雖然有眾多的哈希技術和演算法,但我推薦對密碼使用 bcrypt。可以在此處進一步了解加密哈希函數,但通常不必了解這些函數的基礎細節。在執行哈希運算期間使用了鹽,將鹽作為提供給哈希函數的附加信息,使您(意外或通過暴力)即使找到一個哈希值,也無法校驗其他可能具有類似輸入的哈希值。例如,user_1 有一個與 user_2 的密碼相同的密碼。如果哈希函數中使用了鹽,這兩個用戶的密碼就無法被找到。要進一步了解此函數,此處提供了各種各樣的信息和示例。

加密也是某個輸入與一個輸出之間的一對一映射。一個重要的關鍵區別是,如果您擁有加密密鑰,那麼加密是可逆的。

您可以在以後使用哈希運算來檢查一個輸入與另一個輸入的映射,但您可能並不想直接存儲該輸入(密碼、pin 編號等)。在發送消息時(雙方都有一個用於編碼/解碼的密鑰),或者在您想存儲一些隱私信息(比如家庭地址或信用卡),但需要在以後通過某種方式檢索此信息時,可以使用加密。

前端

因為本文的重點不是前端,所以我們不打算採用任何會增加複雜性的內容或引入另一個令人擔憂的框架。我們將在同一個頁面上採用兩個用於登錄/註冊的表單。除了使用超級簡單的引導指令外,我們不會對這些表單執行任何操作,因為這不是本文的重點。

我們還將輸入從表單提交到後端,而且不打算校驗/創建/設置會話,因為這不屬於本文的討論範圍,而且根據應用程序的目標或目的,涉及的內容可能很廣泛。

創建後端

接下來,我們將在 Node.js 中運行後端,方法是使用 Express 框架和 SQLite 來實現本文所需的最基本的系統。

我們在這裡執行的操作包括:為資料庫創建一個 promise,生成一個鹽,並創建應用程序和簡單中間件來獲取用戶名/密碼,載入一些我們想要使用的庫。

路徑

對於我們的伺服器將要執行的操作,我們將有一個登錄路徑和一個供用戶進行註冊的路徑。為了理解系統中正在發生的事情,我們將這兩條路徑分開了,但它們不會執行任何操作(與會話/cookie 等相關的任何操作)。一旦密碼匹配,我們將(非常簡單地)展示如何對一個密碼執行哈希運算,然後執行校驗。登錄路徑與註冊路徑幾乎是相同的,儘管我們會在該 HTML 表單上檢查電子郵件,但我們不會在任何路徑上執行任何數據驗證。

註冊路徑檢查用戶是否存在於資料庫中,以及我們是否已使用一個經過哈希運算的密碼將其插入資料庫中。請記住,我們不會執行任何操作來減少 SQL 注入或其他各種形式的攻擊/濫用。如果該用戶不存在,我們會使用 bcrypt 哈希函數對密碼執行哈希運算,該函數會在密碼中添加鹽,因為我們向鹽提供了運算的輪數。這種哈希運算使我們能夠以這樣一種方式存儲用戶的密碼 - 將來,如果用戶輸入了密碼,我們就可以檢查密碼。我們自己無法查找該密碼。另外,我們不應將密碼輸出到用戶的日誌中,而且我們可能希望能夠使用資料庫模型來檢查密碼,並將用戶的密碼保存到哈希值中。

儘管登錄路徑幾乎相同(而且我們可以輕鬆重構此路徑來讓它更 DRY,但在這裡提供它是為了便於理解),但有一行稍有不同:

此代碼使用 bcrypt 將經過哈希運算的密碼與用戶在前端輸入的密碼進行比較,並返回 true 或 false。因為鹽已合併到哈希值中,所以我們不需要顯式使用它來進行比較。下面是要運行的完整的 server.js:

儘管登錄路徑幾乎相同(而且我們可以輕鬆地重構此路徑來讓它更 DRY,但在這裡提供它是為了便於理解),但有一行稍有不同:

上面這行使用 bcrypt 將經過哈希運算的密碼與用戶在前端輸入的密碼進行比較,並返回 true 或 false。因為鹽已合併到哈希值中,所以我們不需要顯式使用它來進行比較。下面的代碼清單是要運行的完整的 server.js:

現在安裝依賴項:

yarn add bcrypt express body-parser sqlite。

運行伺服器 Node server.js,打開 http://localhost:8080。然後嘗試登錄,創建一個用戶,並再次登錄。

通過網路發送未加密的密碼!

儘管本文僅展示了如何存儲密碼並對其執行哈希運算,而且您不會保存用戶的明文密碼,但我們仍在瀏覽器與後端之間發送明文,因為我們沒有使用 HTTPS。如果將此示例用在生產環境中,當黑客進入此通信渠道時,他們很容易看到在伺服器與客戶端之間發送的密碼(包括登錄和註冊密碼)。有許多不同的方法可用來實際阻止中間人攻擊,但為了簡單起見,我們將在 Express 中處理它,生成自簽名 SSL 證書作為示例,以說明此工作原理。請記住,這些證書的簽署方式與從 LetsEncrypt 或其他各種 SSL/TLS 證書提供者獲取證書的方式不同。

首先,我們需要通過包管理器或通過 OpenSSL 的官方網站安裝 OpenSSL。在 macOS 上,如果您已安裝 homebrew,可以簡單寫入以下代碼:

brew-install Openssl

接下來,需要運行以下命令來生成一個密鑰和一個證書:

openSSL req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 30

此命令會要求您輸入一些信息,但在最後,您將獲得一個 key.pem 和一個 cert.pem。有了這兩個文件,就可以將以下代碼添加到 server.js 的頂部(請注意,我們現在使用的是來自 Node.js 的 https 標準庫):

此刻,我們將僅使用 HTTPS 並將加密後的密碼發送到伺服器,而且會在將密碼保存到資料庫時執行哈希運算。

最糟的情況:資料庫被泄露


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CIO時代網 的精彩文章:

我國首個IPv6公共DNS發布:亦能解析IPv4

TAG:CIO時代網 |