Protocol-Design
客戶端登錄不發送密碼
我希望有一個系統,其中密碼永遠不會以明文(即使使用 TLS)發送來驗證使用者。我想出了這個協議,但我寧願使用經過驗證的東西。
登記:
- 客戶端(瀏覽器中的 javascript)生成 2048 位 RSA 密鑰對(使用 Forge js)
- 客戶端使用 pbkdf2 68000 輪從使用者密碼生成雜湊
- 客戶端使用 OpenSSH 格式的 AES 128 使用上述雜湊作為密碼對私鑰進行加密
- 客戶端將加密後的私鑰、公鑰、pbkdf2 salt和使用者名發送給伺服器
登錄:
- 客戶端使用登錄名請求加密的私鑰和 pbkdf2 salt
- 客戶端使用 pbkdf2 從使用者密碼生成雜湊,68000 輪和來自伺服器的鹽
- 客戶端使用 pbkdf2 雜湊解密私鑰
- 客戶端向伺服器請求質詢
- 伺服器使用 OAEP-SHA1(使用 cryptography.io)發送使用使用者公鑰加密的質詢
- 客戶端解密挑戰並將明文挑戰發送到伺服器
- 伺服器向客戶端發送有限使用令牌以使用 API
TLDR:是否有登錄協議,客戶端可以在不發送密碼的情況下向伺服器證明真實性。然後,使用者可以將令牌用於在設定時間/幾次呼叫後過期的 API 呼叫。此系統無法使用 oauth。
我可以看到您的協議中的一些弱點。例如,它允許任何攻擊者請求加密的私鑰,從而安裝離線字典或對密碼進行暴力攻擊。(不正確的密碼不會為您提供格式正確的 OpenSSH 密鑰。)
因此這是一個好主意:
我寧願使用經過驗證的東西。
正如評論中提到的,SRP 完全符合您的要求。這是版本 6(a) 協議的描述。
為了防止伺服器受到攻擊(就像使用密碼身份驗證一樣),您需要結合使用 PBKDF2(或其他密碼散列函式)的想法。如果您不希望伺服器在每次登錄嘗試時都計算緩慢的密碼雜湊,您可以使用普通雜湊作為 $ H $ 導出時除外 $ x $ ,只有客戶需要這樣做。或者,如果您使用 SRP 庫(如果可能的話)並且它不支持此功能,您可以計算 $ p $ 您使用 PBKDF2 從實際密碼輸入 SRP。