Protocol-Design

Web 應用程序的 HMAC 密鑰儲存?

  • August 11, 2019

如果要使用 HMAC,即:http: //php.net/manual/en/function.hash-hmac.php,他們究竟在哪裡儲存密鑰?

如果沒有某種安全儲存(即不在本地文件或程式碼中),我覺得使用 HMAC 時就像在自欺欺人(與上述功能一樣)。我錯過了與密鑰儲存相關的內容?

在我們討論關鍵儲存和管理問題之前,我想澄清連結文章中提出的方案,以確保清楚我們在談論什麼。

假設我們pw從使用者那裡獲取身份驗證salttag從數據庫中檢索,並且我們sk從作為密鑰的儲存方法(見下文)中獲取。pw只有當且僅當tag=hmac(sk,salt||pw||salt)持有密碼時,我們才會接受密碼。看起來的原型hmac如下:MessageAuthenticationCode = hmac(SecretKey,Message),其中輸入SecretKey對於受信任的設備是隱含的,它提供了一個參數來指定儲存在設備內部的特定密鑰。


如果您想在重新啟動的伺服器上進行密碼驗證,我真的只看到三個用於儲存密鑰的選項:

  • 使用連接到伺服器的受信任設備。這包括智能卡(它們可能太慢)、可信平台模組(TPM;也可能太慢)和*硬體安全模組*(HSM;可能太貴)
  • 將加密的密鑰儲存在 RAM 中,並將清除的密鑰保存在RAM中,並且需要使用者互動才能解鎖。這可以通過向伺服器發送一個秘密密碼來工作,該密碼允許在 HMAC 密鑰處於靜止狀態時對其進行解密,或者可以使用此協議(使用 EC - ElGamal)進行智能卡/TPM/基於 HSM/基於軟體的遠端解鎖。
  • 臨時儲存加密密鑰,將明文保存在 RAM 中並使用受信任的設備。這意味著您讓伺服器生成秘密 HMAC 密鑰,該密鑰僅保存在 RAM 中,直到重新啟動發生,並且僅在重新啟動時使用受信任的設備。您可以將此與第二種方法結合使用。

現在了解每種方法的細節和權衡。

受信任的設備

您可以為自己獲取一張智能卡並將其安裝在伺服器中。然後,您將要檢查的密碼發送到持有密鑰的卡,並接收相應的密碼雜湊值,並將其與儲存的值進行比較。這可能不適合大規模身份驗證,因為智能卡往往很慢,但它是受信任設備中(第二)最便宜的選擇。

您可以獲得具有可信平台模組(TPM) 的伺服器主機板,並像上一段中的智能卡一樣使用它。然而,TPM 也有同樣的問題:雖然它往往很便宜,但通常速度很慢,不適合大型服務(每秒處理超過 10 個請求)。

此類別中的“最佳”解決方案是硬體安全模組(HSM)。它將像其他兩個一樣使用。無論這些模組往往非常快,並且很可能能夠在很短的時間內處理許多請求。此外,HSM 往往還具有比智能卡和 TPM 更好的安全認證。缺點當然是 HSM 非常昂貴,便宜的起價幾百美元,更好的可達幾萬美元,而智能卡的價格範圍在幾美元到一百美元之間。片。

TL;DR:總的來說,雖然它們提供了最高的安全性,但我認為受信任的設備不會解決您的問題,因為 API、速度和價格限制。

使用者互動

這里基本上有四種不同的選擇。就地或遠端基於密碼或基於公鑰的密鑰解鎖的組合。我將快速描述每一個。

但首先我需要描述這種方法的總體概念。您讓伺服器在 RAM 中生成 HMAC 密鑰並將加密副本儲存在硬碟驅動器上。每次伺服器重新啟動時,HMAC 密鑰都會從 RAM 中擦除,並且需要解鎖加密副本以驗證密碼。這就是使用者互動發揮作用的地方。

第一個版本將在直接和物理連接到伺服器時簡單地輸入密碼。這可以說是需要使用者互動的最安全的解決方案,但另一方面也是最耗時的解決方案,因為每次伺服器重新啟動時都必須插入顯示器和鍵盤,所以你不會想要去做這個。

第二個版本與第一個版本幾乎相同,但這次您將智能卡讀卡器(帶有密碼鍵盤)連接到伺服器,輸入 PIN 並讓卡(非對稱)解密儲存的 HMAC 密鑰。雖然這比第一種方法更安全,但它也存在同樣的問題,因此通常不是一種選擇。

第三個版本改進了第一個版本,通過建立一個到伺服器的TLS(或其他)安全通道並以這種方式傳遞密碼。雖然這顯然不如第一個版本安全,因為存在攔截和中間人攻擊的風險,但它也更具可擴展性。

第四個版本改進了第二個。您將建立到伺服器的安全通道(TLSIPSec、本地網路等),然後在其上執行此協議。這將允許您解密儲存的密鑰,而無需離開伺服器。然而,只有正確的智能卡/私鑰才能解鎖 HMAC 密鑰。這是在啟動時需要使用者互動的遠端解決方案中最安全和最具可擴展性的解決方案。

TL;DR:這可能是一種適合您需求的方法,但可能需要太多的使用者互動才能很好地擴展。當然,無法達到完全基於硬體的解決方案的安全性,這可能是可以接受的,因為可以滿足 API、速度和價格。

重啟時受信任的設備

完全披露:我沒有發明這種方法,而是首先在JeticoBestCrypt VolumeEncryption中觀察到它。

您可以讓伺服器在 RAM 中生成密鑰。現在,您讓密鑰保留在那裡,直到發生計劃的重新啟動,TPM 將加密 HMAC 密鑰並將其儲存到驅動器上。現在伺服器重新啟動,重新啟動後,TPM 將解鎖密鑰,然後將其刪除。這允許無人值守的重新啟動,但問題是如果發生意外重新啟動,密鑰將失去並且無法驗證密碼。積極的一面當然是這將非常好地擴展,並允許快速基於軟體的驗證,同時在必要時使用強大的硬體保護。

TL;DR:雖然此解決方案可以很好地擴展,但它存在密鑰備份問題,以防伺服器在沒有警告的情況下關閉。當然,無法達到完全基於硬體的解決方案的安全性,這可能是可以接受的,因為可以滿足 API、速度和價格。

最優解(?)

這種方法與前一種方法的工作原理相同,只是將 HMAC 密鑰加密備份到驅動器。大多數情況下,伺服器將按照上述方法執行(使用基於軟體的 HMAC 進行驗證),但在重新啟動的情況下,TPM 將啟動並臨時製作用於重新啟動的備份副本。現在,“舊”方法的弱點是沒有針對意外重啟的備份。在這種情況下,使用者互動方法可以啟動並允許對備份密鑰進行解密。這甚至可以解決“盲解密”協議的問題,因為使用者現在很少使用這種方法,而且只有在確定發生了什麼的情況下,允許更強的密鑰保護(如保險庫中的智能卡)以及使用者可以直接看到結果的地方(成功解鎖)。此外,HMAC 密鑰的備份副本可以移動到物理上安全的位置(如保險庫中的 CD),這是獨立協議的問題之一。

TL;DR:這種方法解決了前一種方法的問題,因此有可靠的備份,允許意外重啟和無人看管的計劃重啟。當然,無法達到完全基於硬體的解決方案的安全性,這可能是可以接受的,因為可以滿足 API、速度和價格。

注意:驅動器可能直接連接到處理器/主機板,也可能位於物理上不同的位置。

引用自:https://crypto.stackexchange.com/questions/29847