SSL 雙向認證過程

結合日誌,我們來看一下SSL雙向認證的全過程: 

 

第一步: 客戶端發送ClientHello消息,發起SSL連接請求,告訴服務器自己支持的SSL選項(加密方式等)。 

Bash代碼  收藏代碼
  1. *** ClientHello, TLSv1  


第二步: 服務器響應請求,回覆ServerHello消息,和客戶端確認SSL加密方式: 

Bash代碼  收藏代碼
  1. *** ServerHello, TLSv1  


第三步: 服務端向客戶端發佈自己的公鑰。 

第四步: 客戶端與服務端的協通溝通完畢,服務端發送ServerHelloDone消息: 

Bash代碼  收藏代碼
  1. *** ServerHelloDone  


第五步: 客戶端使用服務端給予的公鑰,創建會話用密鑰(SSL證書認證完成後,爲了提高性能,所有的信息交互就可能會使用對稱加密算法),並通過ClientKeyExchange消息發給服務器: 

Bash代碼  收藏代碼
  1. *** ClientKeyExchange, RSA PreMasterSecret, TLSv1  


第六步: 客戶端通知服務器改變加密算法,通過ChangeCipherSpec消息發給服務端: 

Bash代碼  收藏代碼
  1. main, WRITE: TLSv1 Change Cipher Spec, length = 1  


第七步: 客戶端發送Finished消息,告知服務器請檢查加密算法的變更請求: 

Bash代碼  收藏代碼
  1. *** Finished  


第八步:服務端確認算法變更,返回ChangeCipherSpec消息 

Bash代碼  收藏代碼
  1. main, READ: TLSv1 Change Cipher Spec, length = 1  


第九步:服務端發送Finished消息,加密算法生效: 

Bash代碼  收藏代碼
  1. *** Finished  


那麼如何讓服務端也認證客戶端的身份,即雙向握手呢?其實很簡單,在服務端代碼中,把這一行: 

Java代碼  收藏代碼
  1. ((SSLServerSocket) _socket).setNeedClientAuth(false);  


改成: 

Java代碼  收藏代碼
  1. ((SSLServerSocket) _socket).setNeedClientAuth(true);  


通過比對單向認證的日誌輸出,我們可以發現雙向認證時,多出了服務端認證客戶端證書的步驟: 

Bash代碼  收藏代碼
  1. *** CertificateRequest  
  2. Cert Types: RSA, DSS  
  3. Cert Authorities:  
  4. <CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn>  
  5. <CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn>  
  6. *** ServerHelloDone  


Bash代碼  收藏代碼
  1. *** CertificateVerify  
  2. main, WRITE: TLSv1 Handshake, length = 134  
  3. main, WRITE: TLSv1 Change Cipher Spec, length = 1  


在 @*** ServerHelloDone@ 之前,服務端向客戶端發起了需要證書的請求 @*** CertificateRequest@ 。 

在客戶端向服務端發出 @Change Cipher Spec@ 請求之前,多了一步客戶端證書認證的過程 @*** CertificateVerify@ 。 

客戶端與服務端互相認證證書的情景,可參考下圖: 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章