熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

用JSSE定制SSL連接

2013-11-15 11:43:47  來源: JSP教程 

  JSSE(Java Security Socket ExtensionJava安全套接字擴展)是Sun為了解決在Internet上的安全通訊而推出的解決方案它實現了SSL和TSL(傳輸層安全)協議在JSSE中包含了數據加密服務器驗證消息完整性和客戶端驗證等技術通過使用JSSE開發人員可以在客戶機和服務器之間通過TCP/IP協議安全地傳輸數據這篇文章主要描述如何使用JSSE接口來控制SSL連接
  首先我通過一個簡單的客戶機/服務器程序來介紹如何利用JSSE進行編程當建立客戶端時我們需要配置KeyStore和TrustStore文件這樣在程序中我們才可以從客戶端的文件系統中加載它們然後文章將討論授權和身份驗證方面的問題通過從KeyStore中選擇不同的授權客戶端程序可以連接到不同的服務器
  運行例子程序
  下載例子程序
  在運行JSSE程序前你需要正確安裝JSSE如果你安裝了JSE JSSE已經被自動安裝並配置好了如果你使用的是其他版本的Java你需要從官方站點上下載並安裝JSSE安裝過程這裡就不再贅述由於JSSE是在JSE 中才成為標准的並且JSE 中的JSSE和以前的JSSE有一些細微的差別而且文中的例子都是在JSE 下調試的因此推薦你使用JSE 運行這些例子
  
  在深入介紹JSSE之前讓我們來一個簡單的客戶機/服務器程序程序中包含了兩個文件SimpleSSLServer和SimpleSSLClient在運行程序之前你需要配置下面這些KeyStore和TrestStore文件
  · 一個客戶端的KeyStore文件該文件中包含了對Alice和Bob的授權
  · 一個服務器端的KeyStore文件該文件中包含了對server的授權
  · 一個名為clientTrust的客戶端TrustStore文件該文件中包含了對server的授權
  · 一個名為serverTrust的服務器端TrustStore文件該文件中包含了對Alice和Bob的授權
  使用keytool可以幫助你創建這些文件(該工具在Java的bin目錄下)
  · 一個客戶端的KeyStore文件該文件中包含了對Alice和Bob的授權
  在命令窗口中輸入下面的命令
  keytool genkey alias alice keystore clientKeys
  窗口中會出現下面的提示根據提示輸入相應的信息
  
  輸入keystore密碼 password
  您的名字與姓氏是什麼?
   [Unknown] Alice
  您的組織單位名稱是什麼?
   [Unknown] Development
  您的組織名稱是什麼?
   [Unknown] DCQ
  您所在的城市或區域名稱是什麼?
   [Unknown] ChongQing
  您所在的州或省份名稱是什麼?
   [Unknown] ChongQing
  該單位的兩字母國家代碼是什麼
   [Unknown] CH
  CN=Alice OU=Development O=DCQ L=ChongQing ST=ChongQing C=CH 正確嗎?
   [否]
  輸入的主密碼
  (如果和 keystore 密碼相同按回車)
  通過相同的方式可以建立對Bob的授權
  keytool genkey alias bob keystore clientKeys
  注意在名字與姓氏一欄中填寫Bob在完成後可以鍵入下面的命令來檢測是否已經正確完成了授權
  keytool list v keystore clientKeys
  · 一個服務器端的KeyStore文件該文件中包含了對server的授權
  
  在命令窗口中鍵入下面的命令
  keytool genkey alias server keystore serverKeys
  注意將密碼設為password名字與姓氏設定為Server完成授權後同樣可以通過上面提到的命令來檢測
  · 一個名為clientTrust的客戶端TrustStore文件該文件中包含了對server的授權以及一個名為serverTrust的服務器端TrustStore文件該文件中包含了對Alice和Bob的授權
  keytool export alias server keystore clientKeys file servercer
  輸入keystore密碼 password
  保存在文件中的認證
  keytool export alias alice keystore clientKeys file alicecer
  輸入keystore密碼 password
  保存在文件中的認證
  keytool export alias bob keystore clientKeys file bobcer
  輸入keystore密碼 password
  保存在文件中的認證
  這樣keytool就在當前目錄下創建了三個授權文件然後我們將servercer文件導入到clientTrust文件中將alicecer和bobcer導入到serverTruest文件中
  
  keytool import alias server keystore clientTrust file servercer
  keytool import alias alice keystore serverTrust file alicecer
  keytool import alias bob keystore serverTrust file bobcer
  到目前為止在當前目錄下包含clientKeysserverKeysclientTrustserverTrust四個文件完成了KeyStore和TrustStore的設置後就可以運行例子程序了首先需要運行服務器程序
  java sslkeyStore=serverKeys
   sslkeyStorePassword=password
   ssltrustStore=serverTrust
   ssltrustStorePassword=password SimpleSSLServer
  在命令行中我們指定了keyStore屬性為serverKeys由於服務器程序需要獲得客戶端的授權信息我們指定trustStore為serverTrust這樣SSLSimpleServer就可以驗證由SSLSimpleClient提供的授權信息當服務器程序成功運行後你會看到下面的提示
  SimpleSSLServer running on port
  這時候服務器會等待客戶端發出建立連接的申請如果你希望在另一個端口上運行服務器程序可以在命令中指定port xxx參數其中xxx是端口號
  
  然後在另一個命令窗口中運行客戶端程序
  
  java sslkeyStore=clientKeys
   sslkeyStorePassword=password
   ssltrustStore=clientTrust
   ssltrustStorePassword=password SimpleSSLClient
  客戶端程序會試圖向本機的端口建立SSL連接同樣你可以通過port參數指定端口號也可以通過host參數指定主機名稱當連接成功後會出現下面的提示信息
  
  Connected
  同時在服務器端會提示用戶客戶端已經連接成功
  
  SimpleSSLServer
  
  讓我們先來看一下SimpleSSLServer在main()方法中程序獲得了缺省的SSLServerSocketFactory對象然後利用SSLServerSocketFactory創建一個SimpleSSLServer對象最後調用start()方法啟動SimpleSSLServer對象
  
  SSLServerSocketFactory ssf=
  (SSLServerSocketFactory)SSLServerSocketFactorygetDefault();
  SimpleSSLServer server=new SimpleSSLServer(ssf port);
  serverstart();
  由於服務器是在一個單獨的線程中運行的main()方法啟動了服務器之後就退出了start()方法啟動了一個新的線程該線程執行run()方法中的代碼在run()方法中創建了一個SSLServerSocket對象然後設定服務器需要進行客戶端驗證
  SSLServerSocket serverSocket= (SSLServerSocket)serverSocketFactorycreateServerSocket(port);
  serverSocketsetNeedClientAuth(true);
  調用run()方法後程序進入了一個死循環等待客戶端的連接申請循環中的每個Socket對應一個HandshakeCompletedListener對象(該對象是用來顯示客戶驗證信息中的標識名稱[distinguished name]的)Socket的InputStream對象被包裝在一個InputDisplayer對象中這個InputDisplayer對象運行在另外一個線程中用來將Socket接收到的數據發送到Systemout下面的代碼是SimpleSSLServer中的主循環體
  while (true) {
   String ident=StringvalueOf(id++);
   //監聽連接請求
   SSLSocket socket=(SSLSocket)serverSocketaccept();
   //通過使用HandshakeCompletedListener對象程序進行授權驗證
   HandshakeCompletedListener hcl=new SimpleHandshakeListener(ident);
   socketaddHandshakeCompletedListener(hcl);
   InputStream in=socketgetInputStream();
   new InputDisplayer(ident in);
  }
  程序中的SimpleHandshakeListener類實現了HandshakeCompletedListerner接口在SimpleHandshakeListener類中實現了handshakeCompleted()方法該方法在SSL握手階段完成後將被JSSE調用它將顯示出客戶端的標識名稱
  class SimpleHandshakeListener implements HandshakeCompletedListener
  {
   String ident;
   /**
   * 構造函數
   */
   public SimpleHandshakeListener(String ident)
   {
   thisident=ident;
   }
   /**當SSL握手過程完成後該方法被激活 */
   public void handshakeCompleted(HandshakeCompletedEvent event)
   {
   //顯示授權信息
   try {
   XCertificate
   cert=(XCertificate)eventgetPeerCertificates()[];
   String peer=certgetSubjectDN()getName();
   Systemoutprintln(ident+: Request from +peer);
   }
   catch (SSLPeerUnverifiedException pue) {
   Systemoutprintln(ident+: Peer
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19512.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.