Authentication

通過 HTTPS 發送散列密碼是否安全或最安全的身份驗證方法是什麼?

  • January 29, 2021

我對 HTTPS 和 Diffie-Hellman 密鑰交換的初步理解是,客戶端和伺服器可以通過基於它們的私有密鑰和共享密鑰生成相同的密鑰來建立安全連接。然後該密鑰用於加密/解密在雙方之間來回傳遞的數據。

這意味著我已經建立了一個安全連接,但沒有說明連接到我的伺服器的客戶端的身份。可以是任何擁有瀏覽器的人。我的問題是,為了在已經建立加密連接後辨識客戶端,通過在所述連接上發送使用者名和散列密碼來建立使用者身份是否安全?這是一種標準程序嗎?

在我的大多數案例中,我的客戶端和伺服器將是我編寫的 NodeJS 或 Java 應用程序,其中一些在同一台機器上執行,也可能在不同位置的不同伺服器上執行,所以我不太關心創建任何一種允許使用者註冊的系統。預設的散列密碼是否足夠安全,或者我應該使用 SSH 等非對稱密鑰?我只是不完全確定優點/缺點是什麼,或者驗證客戶端的標準方法是什麼。我什至需要散列任何東西,還是我可以讓使用者發送一個明文密碼並根據我的數據庫檢查它,因為無論如何連接已經加密?

網站最常用的方法是將密碼本身發送到伺服器,然後伺服器使用 Argon2id 或 bcrypt 等“密碼雜湊函式”(不是加密雜湊)創建摘要(包含一些設置,每個帳戶唯一的鹽和密碼的雜湊值),然後將摘要與儲存在該使用者的伺服器上的值進行比較。

可以這樣做兩次:您可以在客戶端使用密碼散列函式,然後將摘要發送到伺服器,然後對完整摘要使用另一個密碼散列函式。這可以通過客戶端和伺服器上的工作因素的不同設置來完成,以減少伺服器需要計算的工作量。伺服器應該使用第二個鹽,每個帳戶仍然是唯一的。這樣做的最大缺點是大多數客戶端沒有密碼雜湊函式的程式碼,每個帳戶的儲存成本更高(需要儲存額外的摘要,因此每個使用者可能多出大約 64 個字節),以及登錄過程需要向客戶發送工作因素設置和一種鹽。

對於某些應用程序,可以讓客戶端生成非對稱密鑰對,向伺服器發送公共部分,然後通過簽署伺服器發送的質詢進行身份驗證。例如,伺服器可以向客戶端發送一個 32 字節的隨機值,客戶端可以對其進行簽名,如果簽名對儲存的公鑰有效,則伺服器授予訪問權限。SSH 就是這樣做的。Ed25519 SSH 密鑰很小,並且對 SSH 格式有很多支持。缺點是使用者需要保存這些密鑰,失去私鑰意味著失去訪問權限,洩露私鑰允許攻擊者訪問(就像密碼一樣)。如果可行**,這是最安全的選擇**。

還有一些 saPAKE,比如 OPAQUE good article here,不需要向伺服器發送密碼副本(或密碼的雜湊),但它們還沒有標準化。我暫時避免使用這些,但請注意它們是否標準化。請閱讀那篇文章,它比我在這裡更全面地描述了常見的密碼案例。

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