2011-02-10 91 views
0

我不是一個安全專家,所以我正在尋找人們在我設計的身份驗證方案中捅漏洞,或者指出我更好,現有方案,該方案滿足同一目標:尋求輸入:保持服務器會話沒有任何服務器狀態

問題

概述我在該客戶端維護會話生命週期的接口(這是一個Web服務器上的HTTP會話,但它其實並不重要)。

無狀態服務器提供了一些服務,需要調用者進行身份驗證(服務器有能力執行此身份驗證)。

但是,服務器不必在每次調用時都必須驗證調用者,例如通過在每次調用中傳遞憑據。 (驗證過程可能很昂貴。)

也不希望在服務器上維護會話狀態。首先,它只是要求一個脆弱的解決方案,在客戶端和服務器上都有獨立的會話超時(客戶端上的一個無法擺脫),並且爲了獲得可靠的會話生存期,服務器超時似乎是必要的在服務器上(而不是依靠客戶端在適當的時間明確結束會話)。另一方面,服務器沒有設置爲存儲這種狀態。

服務器有明確的authenticate方法。問題是:服務器如何驗證當調用另一個方法時,調用方先前已使用authenticate方法進行身份驗證,而不在服務器上存儲任何會話狀態?

建議的解決方案

這裏有一個方案,我想出來的:

authenticate方法接受證書作爲輸入參數。在成功認證後,服務器返回兩件事:

  • 指示執行身份驗證的時間的時間戳。
  • {用戶名,時間戳}的元組的加密版本,使用私鑰

加密在更進一步的方法調用,客戶端通過這兩個值回服務器。服務器然後解密加密的{username,timestamp}元組。如果解密的時間戳與客戶端發送的未加密值匹配,服務器就知道客戶端先前已經過身份驗證(因爲這是獲取有效加密值的唯一方法)。解密的用戶名告訴服務器哪個用戶已被認證。

加密密鑰的有效期可以通過僅允許當前時間的x小時內的時間戳來強制執行。這與會話超時不同,但它限制了惡意方可能使用受損時間戳的窗口。

所以

我擔心,該方案是對多種方式天真。你看到什麼弱點或不合邏輯?

回答

0

如果有人關心(這似乎不太可能,因爲這個問題已經得到了很多關注!),我們最終實現了一個如上所述的方案。

一些細節有所不同,但:

  • 服務器創建基於用戶名,會話開始時間戳(傳回給用戶)會話令牌,和鹽。
  • 客戶端不會將此令牌傳遞迴服務器。相反,從與該令牌連接的整個請求內容創建MD5散列。
  • 將MD5哈希值與時間戳和用戶名(以及請求)一起發送到服務器。服務器然後重新創建會話令牌並執行相同的哈希算法。如果MD5哈希匹配:有效的請求。
相關問題