2011-10-31 108 views
4

我正在使用帶SSL的HTTP使用來自Android設備的Web服務。自簽名(不可信)證書用於客戶端認證SSL和公鑰安全

我對公鑰/私鑰如何用於SSL有一般的理解。根據我的理解,我可以清楚地看到如何使用證書來建立安全連接並安全傳輸數據。但是,我不明白它們是如何用於客戶端身份驗證的,因爲證書包含公鑰並且不被保密。

我有幾個問題:

我在哪裏可以閱讀有關SSL和證書可用於客戶端身份驗證?

即使證書未公開...通過訪問瀏覽器中的HTTPS URL,我可以查看並保存證書。然後,我可以將證書打包在密鑰存儲區中並從應用程序中使用它。

this post傑里米Huiskamp寫道

客戶端驗證會自動進行,當服務器請求 它

...所以客戶端身份驗證以及數據加密可以使用證書進行?

編輯回答我的問題的第一部分:客戶端密鑰庫不僅應包含服務器的公鑰,而且還應該包含客戶端的私鑰。那麼服務器必須能夠使用客戶端的公鑰解密?這是否意味着密鑰庫應該有兩個證書?

回答

8

首先,快速點關於公鑰密碼的術語:

  • 你簽名和解密/解密使用私鑰,
  • 您驗證(簽名)並使用公鑰加密/加密。

(你不會真的「解密」使用公共密鑰)。

使用SSL/TLS有或無客戶端身份驗證,服務器提供一個證書(*)爲它具有專用鍵。服務器在SSL/TLS握手期間(在連接開始時)發送其證書,並且能夠解密客戶端使用其私鑰(私鑰)發送的內容。私鑰和證書存儲在服務器的密鑰存儲區(或者如果未在Java中實現,則是等效的)。

作爲此操作的一部分,客戶端使用其信任庫(它是一種包含可信證書的密鑰庫的形式)來驗證服務器證書。服務器證書可以通過顯式位於信任庫中來信任,或者在大多數情況下通過鏈接到信任庫(PKI)中的可信CA證書來信任。

Java中的密鑰倉庫和信任倉庫之間的術語可能有點混淆,您可以找到更多details in this answer

關於您的問題,客戶端的信任庫不包含服務器的公鑰,而是其證書或證書,它應該是可驗證的。 (這不僅僅是擁有公鑰,而是知道它是誰,使用證書中的其他信息。)

除此之外,當您使用客戶端證書身份驗證時,還有一個信任庫(或等效)和客戶端的密鑰庫,因爲角色爲此目的被顛倒過來。

在使用客戶端身份驗證的SSL/TLS握手中,服務器向客戶端請求發送證書(如果可用)的證書。

在握手結束時,客戶端發送一個CertificateVerify消息,該消息使用客戶端證書私鑰在客戶端和服務器之間交換迄今爲止所有消息(因此它們都是已知的)。然後,服務器可以根據它作爲此交換的一部分獲得的客戶端證書中的公鑰驗證此簽名。這向服務器證明,在客戶端的任何人擁有與其發送的證書中的公鑰相對應的私鑰。

服務器的下一步是驗證是否信任該證書,即是否信任身份和公鑰之間的綁定,如證書中所示和「密封」。 這通常是使用PKI完成的,您可以根據已知CA檢查證書,或者如果您的部署環境足夠小,則針對一組固定的可信證書進行檢查。 (可以有alternative methods of verification,但他們的可用性將真正取決於您要部署該系統的情況下)。

因此,對於你的第二個問題:

  • 客戶密鑰庫應該包含至少客戶的證書和私鑰。
  • 客戶端信任庫應該包含服務器證書或可用於驗證服務器證書的CA證書。

由於兩個密鑰庫和信任是用於不同目的的密鑰庫(在存儲格式感,通常是一個文件),它通常可以使用相同的密鑰存儲服務密鑰庫和信任的兩個目的。

(*)有些密碼套件不依賴證書,但對於這個問題來說,這是非同尋常的。

2

證書只是將身份綁定到公鑰上。這種綁定不是祕密的,所以不需要保密證書。如果我有約翰史密斯的證書,我可以證明約翰史密斯擁有與特定公鑰對應的密鑰。但是因爲我不知道那個祕密鑰匙,所以證書對我來說沒有用處。

當通過證書進行身份驗證時,一個步驟總是讓出示證書的人證明他們知道與證書中的公鑰對應的祕密密鑰。如果您無法通過該步驟,則認證失敗。

服務器的密鑰庫應該有服務器的證書。客戶的密鑰庫應該有客戶的證書。客戶端會將其證書提供給服務器,這樣服務器將以這種方式瞭解客戶端的公鑰。 (反之亦然)。