ssl/https配置與實現

 SSL協議使用不對稱加密技術實現會話雙方之間信息的安全傳遞。可以實現信息傳遞的保密性、完整性,並且會話雙方能鑑別對方身份。不同於常用的http協議,我們在與網站建立SSL安全連接時使用https協議,即採用的方式來訪問。

當我們與一個網站建立https連接時,我們的瀏覽器與Web Server之間要經過一個握手的過程來完成身份鑑定與密鑰交換,從而建立安全連接。具體過程如下: 
1. 用戶瀏覽器將其SSL版本號、加密設置參數、與session有關的數據以及其它一些必要信息發送到服務器。 
2. 服務器將其SSL版本號、加密設置參數、與session有關的數據以及其它一些必要信息發送給瀏覽器,同時發給瀏覽器的還有服務器的證書。如果配置服務器的SSL需要驗證用戶身份,還要發出請求要求瀏覽器提供用戶證書。 
3. 客戶端檢查服務器證書,如果檢查失敗,提示不能建立SSL連接。如果成功,那麼繼續。 
4. 客戶端瀏覽器爲本次會話生成pre-master secret,並將其用服務器公鑰加密後發送給服務器。 
5. 如果服務器要求鑑別客戶身份,客戶端還要再對另外一些數據簽名後並將其與客戶端證書一起發送給服務器。 
6. 如果服務器要求鑑別客戶身份,則檢查簽署客戶證書的CA是否可信。如果不在信任列表中,結束本次會話。如果檢查通過,服務器用自己的私鑰解密收到的pre-master secret,並用它通過某些算法生成本次會話的master secret。 
7. 客戶端與服務器均使用此master secret生成本次會話的會話密鑰(對稱密鑰)。在雙方SSL握手結束後傳遞任何消息均使用此會話密鑰。這樣做的主要原因是對稱加密比非對稱加密的運算量低一個數量級以上,能夠顯著提高雙方會話時的運算速度。 
8. 客戶端通知服務器此後發送的消息都使用這個會話密鑰進行加密。並通知服務器客戶端已經完成本次SSL握手。 
9. 服務器通知客戶端此後發送的消息都使用這個會話密鑰進行加密。並通知客戶端服務器已經完成本次SSL握手。 
10. 本次握手過程結束,會話已經建立。雙方使用同一個會話密鑰分別對發送以及接受的信息進行加、解密。

tomcat實現SSL配置
第一步 生成KeyStore

keytool -genkey -alias tomcat -keyalg RSA –keysize 1024 –validity 730 -keystore D:\server.keystore

輸入keystore密碼: ************ [Unknown]: localhost [Unknown]: dept [Unknown]: Inc [Unknown]: bj [Unknown]: bj [Unknown]: CN
CN=localhost, OU= dept, O= Inc, L=bj, ST=bj, C=CN 正確嗎?
[否]: Y
Ychangeit (回車)

注意: localhost,是網站的域名或者ip,根據實際情況填寫,比如 192.168.0.85 否則會出現證書上的名稱無效,或者與站點名稱不匹配。

建議:將生成的 server.keystore文件,放到%TOMCAT_HOME%或其子目錄中(如:%TOMCAT_HOME%/conf)

(其實放哪裏都一樣,只是放到%TOMCAT_HOME%裏面會方便一些)

第二步 修改server.xml

修改%TOMCAT_HOME%/conf/server.xml

去掉下面SSL HTTP那個註釋,修改爲如下:

<Connector port="8443" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" 
     SSLEnabled="true"
     maxThreads="150"  
     scheme="https"  
     secure="true"  
     clientAuth="false"  
     sslProtocol="TLS"    
     keystoreFile="/conf/server.keystore"  
     keystorePass="changeit" 
/>  
keystoreFile 是server.keystore放置的位置,keystorePass是密碼 (默認密碼是changeit)

第三步

重啓Tomcat,訪問地址

(附錄:)tomcat的配置文件SSL部分詳細說明
配置文件server.xml,SSL部分: <!-- A "Connector" represents an endpoint by which requests are received 
        Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)   
        Java AJP   Connector: /docs/config/ajp.html 
        APR (HTTP/AJP) Connector: /docs/apr.html   
        Define a non-SSL HTTP/1.1 Connector on port 8080  
>  
<Connector  port="8443" maxHttpHeaderSize="8192"  
        maxThreads="150"  
        minSpareThreads="25"  
        maxSpareThreads="75" 
        enableLookups="false"  
        disableUploadTimeout="true" 
        acceptCount="100"  
        scheme="https"  
        secure="true"  
        clientAuth="false"  
        sslProtocol="TLS"  
        keystoreFile="D:/Tomcat/conf/tomcatKey.keystore"  
        keystorePass="changeit"  
        algorithm="SunX509"  
/>  
屬性說明: port:這個port屬性(默認值是8443)是 TCP/IP端口數碼,Tomcat在其上監聽安全連接。你可以把它更改成任何你願意要的數值(如默認的https通信,數目是443)。不過,在許多操作系統中,要想在比1024小的端口數碼上運行Tomcat,需要特殊的設置(它超出了這個文檔資料的範圍)。 redirectPort: 如果你在這裏更改端口數值,你還必須更改在non-SSL連接器上的redirectPort 這個屬性特定的值。這允許Tomcat自動地redirect那些試圖訪問有安全限制頁面的用戶,指明根據 Servlet 2.4 Specification要求,SSL是必需的 clientAuth: 如果你想要Tomcat要求所有的SSL客戶在使用這個socket時出示用戶認證書,把這個值設定爲 true 。如果你想要Tomcat要求出示用戶認證書,但是如果沒有認證書也可以, 就把這個值設定爲want 。 keystoreFile: 如果你產生的keystore文件不在Tomcat期望的默認地方(一個叫做.keystore 的文件在Tomcat運行的主目錄),就添加這個屬性。你可以指定一個絕對路徑名稱, 或者一個由$CATALINA_BASE環境變量而派生的相對路徑名稱。 keystorePass: 如果你使用一個不同的keystore(以及認證書)密碼,而不是Tomcat期望的密碼 (就是changeit),添加這個元素。 keystoreType: 如果使用一個PKCS12 keystore的話,就添加這個element。 有效的值是JKS 和 PKCS12 sslProtocol: 要在這個socket上被使用的加密/解密協定。如果你在使用Sun的JVM,我們不提倡更改 這個值。據報道,TLS協定的IBM's 1.4.1 實現與一些通用的瀏覽器不兼容。 如果是這樣,就使用value SSL ciphers: 這個socket允許使用的由逗號分隔開的加密密碼列單。默認的情況下,任何可用的密碼都允許被使用。 algorithm: 可用的X509算法。默認是Sun的實現( SunX509 )。 對於IBM JVMs,你應該使用值 IbmX509。對於其他賣主,查閱JVM文檔資料來 找正確的值。 truststoreFile: 用來驗證用戶認證書的TrustStore文件。 truststorePass: 訪問TrustStore的密碼。默認值就是keystorePass的值。 truststoreType: 如果你在使用與KeyStore不同格式的TrustStore,添加這個元素。 合法的值是JKS和PKCS12 keyAlias: 如果 keystore 裏面有多個 key,你可以爲用這個選項爲加入的 key 起一個名字。 如果沒有指定名字,使用時 keystore 內的第一個 key 將會被使用。

此前我一直對https/ssl如何保護數據不被竊 聽有點疑問,因爲服務器的證書是公開的,只能實行上行方向的數據加密,下行數據的加密我一直認爲是瀏覽器會自動生成一個客戶端的密鑰對並將公鑰發給服務器。仔細研究了https/ssl後發現其實並不像我想的那樣,這裏面既有非對稱加密,又因爲性能原因使用了對稱加密。

基本的加解密算法類型也就這兩種:

對稱加密 :密鑰只有一個,加密解密爲同一個密碼,且加解密速度快,典型的對稱加密算法有DES、AES等;

非對稱加密 :密鑰成對出現(且根據公鑰無法推知私鑰,根據私鑰也無法推知公鑰),加密解密使用不同密鑰(公鑰加密需要私鑰解密,私鑰加密需要公鑰解密),相對對稱加密速度較慢,典型的非對稱加密算法有RSA、DSA等。

明白了這兩種加密類型,具體的認證過程就容易理解了:

客戶端瀏覽器連接到https/ssl服務器,併發送ssl版本號等信息到服務器,協商此次連接使用的版本和參數。

服務器根據客戶端發來的協商數據和自身支持的特性返回客戶端協商參數,並且將服務器的證書發送給客戶端,服務器的證書裏包括用於非對稱加密的服務器的公鑰。

客戶端收到服務器的證書,可以用於鑑別服務器身份,防止假冒的服務器。但最重要的用處是將一段由客戶端瀏覽器隨機生成的數據pre-master secret用服務器證書裏的公鑰進行加密,發給服務器。注意,因爲這段加密的數據只由用服務器的私鑰才能解密,所以pre-master secret不會被人監聽到。

服務器收到加密後的pre-master secret數據後,用自己的私鑰解密得到原始的pre-master secret,並使用一定算法得到對稱加密的密鑰master secret。

客戶端也根據同樣的算法得到master secret。

至此,客戶端和服務器之間的上/下行數據傳送使用對稱加/解密,初始密鑰爲master secret。常用的對稱加密算法有RC4,AES等。

經過這些步驟就可以保證https/ssl上下行數據不被監聽並且加/解密速度也可以接受。

1. 生成證書

  這裏用到的文件,我們存放在D:/SSL/文件夾內,其中D:/SSL/server/內的文件是要交給服務器用的,D:/SSL/client/內的文件是要交給客戶端用的。

  1.1生成服務端證書

開始-運行-CMD-在dos窗口執行下執行命令:

keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:/SSL/server/tomcat.keystore -dname "CN=127.0.0.1,OU=zlj,O=zlj,L=Peking,ST=Peking,C=CN" -validity 3650 -storepass zljzlj -keypass zljzlj

說明:

keytool 是JDK提供的證書生成工具,所有參數的用法參見keytool –help

-genkey 創建新證書

-v 詳細信息

-alias tomcat 以”tomcat”作爲該證書的別名。這裏可以根據需要修改

-keyalg RSA 指定算法

-keystore D:/SSL/server/tomcat.keystore 保存路徑及文件名

-dname "CN=127.0.0.1,OU=zlj,O=zlj,L=Peking,ST=Peking,C=CN" 證書發行者身份,這裏的CN要與發佈後的訪問域名一致。但由於我們是自己發行的證書,如果在瀏覽器訪問,仍然會有警告提示。

-validity 3650證書有效期,單位爲天

-storepass zljzlj 證書的存取密碼

-keypass zljzlj 證書的私鑰

    1.2 生成客戶端證書 

    執行命令:
keytool ‐genkey ‐v ‐alias client ‐keyalg RSA ‐storetype PKCS12 ‐keystore D:/SSL/client/client.p12 ‐dname "CN=client,OU=zlj,O=zlj,L=bj,ST=bj,C=CN" ‐validity 3650 ‐storepass client ‐keypass client 

說明:
    參數說明同上。這裏的-dname 證書發行者身份可以和前面不同,到目前爲止,這2個證書可以沒有任何關係。下面要做的工作纔是建立2者之間的信任關係。

    1.3 導出客戶端證書 
    執行命令:
keytool ‐export ‐alias client ‐keystore D:/SSL/client/client.p12 ‐storetype PKCS12 ‐storepass client ‐rfc ‐file D:/SSL/client/client.cer 

說明:

-export 執行導出

-file 導出文件的文件路徑

    1.4 把客戶端證書加入服務端證書信任列表 

    執行命令:
keytool ‐import ‐alias client ‐v ‐file D:/SSL/client/client.cer ‐keystore D:/SSL/server/tomcat.keystore ‐storepass zljzl 

說明:

參數說明同前。這裏提供的密碼是服務端證書的存取密碼。

    1.5 導出服務端證書 

    執行命令:
keytool -export -alias tomcat -keystore D:/SSL/server/tomcat.keystore -storepass zljzlj -rfc -file D:/SSL/server/tomcat.cer 
  
說明:
把服務端證書導出。這裏提供的密碼也是服務端證書的密碼。

    1.6 生成客戶端信任列表 

    執行命令:
keytool -import -file D:/SSL/server/tomcat.cer -storepass zljzlj -keystore D:/SSL/client/client.truststore -alias tomcat –noprompt

說明:
讓客戶端信任服務端證書

2. 配置服務端爲只允許HTTPS連接

    2.1 配置Tomcat 目錄下的/conf/server.xml 

Xml代碼  
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"     
   maxThreads="150" scheme="https" secure="true" clientAuth="true"     
   sslProtocol="TLS" keystoreFile="D:/SSL/server/tomcat.keystore"     
   keystorePass="zljzlj" truststoreFile="D:/SSL/server/tomcat.keystore"     
   truststorePass="zljzlj" />   

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"  
   maxThreads="150" scheme="https" secure="true" clientAuth="true"  
   sslProtocol="TLS" keystoreFile="D:/SSL/server/tomcat.keystore"  
   keystorePass="zljzlj" truststoreFile="D:/SSL/server/tomcat.keystore"  
   truststorePass="zljzlj" />  
說明:
在server.xml裏面這段內容本來是被註釋掉的,如果想使用https的默認端口443,請修改這裏的port參數。其中的clientAuth="true" 指定了雙向證書認證。

    2.2 配置服務端項目web.xml 
    在<welcome-file-list>之後增加:
Xml代碼  
<security-constraint>     
   <web-resource-collection>     
     <web-resource-name>services</web-resource-name>     
     <url-pattern>/services/*</url-pattern>     
   </web-resource-collection>     
   <user-data-constraint>     
     <transport-guarantee>CONFIDENTIAL</transport-guarantee>     
   </user-data-constraint>     
</security-constraint>    

<security-constraint>  
   <web-resource-collection>  
     <web-resource-name>services</web-resource-name>  
     <url-pattern>/services/*</url-pattern>  
   </web-resource-collection>  
   <user-data-constraint>  
     <transport-guarantee>CONFIDENTIAL</transport-guarantee>  
   </user-data-constraint>  
</security-constraint>   
說明:
這裏限制了WEB service服務地址的訪問必須爲https連接。<url-pattern>要根據你的web service服務地址配置。

3. 修改客戶端代碼 
在執行訪問之前,增加:
Java代碼  
System.setProperty("javax.net.ssl.trustStore", "D:/SSL/client/client.truststore");     
System.setProperty("javax.net.ssl.trustStorePassword","zljzlj");     
System.setProperty("javax.net.ssl.keyStoreType","PKCS12") ;     
System.setProperty("javax.net.ssl.keyStore","D:/SSL/client/client.p12") ;     
System.setProperty("javax.net.ssl.keyStorePassword","client") ;     
     
String endPoint="https://127.0.0.1:8443/easbCut/services/ApplyFormService";     
...    

System.setProperty("javax.net.ssl.trustStore", "D:/SSL/client/client.truststore");  
System.setProperty("javax.net.ssl.trustStorePassword","zljzlj");  
System.setProperty("javax.net.ssl.keyStoreType","PKCS12") ;  
System.setProperty("javax.net.ssl.keyStore","D:/SSL/client/client.p12") ;  
System.setProperty("javax.net.ssl.keyStorePassword","client") ;  
  
String endPoint="https://127.0.0.1:8443/easbCut/services/ApplyFormService";  
...   通過設置參數來指定客戶端連接時所使用的客戶端證書,這裏還可以採用修改JVM啓動參數的的方式來執行,但出於不影響其他功能的考慮,這裏採用System.setProperty的方式來設置這些參數,在使用結束後,可以還原這些參數配置。

做爲客戶端的開發者,可以把拿到的證書文件後,只執行步驟3。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章