如何用Tomcat和Openssl構建HTTPS雙向認證環境(HTTPS用戶端認證)

來源:互聯網
上載者:User

 

本文將介紹如何利用Tomcat的HTTPS功能,和一個自己建立的CA,來構建WEB伺服器憑證和個人數位憑證,最終建成一個HTTPS雙向認證環境(可以用於測試目的)。本文構建HTTPS雙向認證的商務程序大致如下:
  1. 建立WEB伺服器公開金鑰密鑰,並產生伺服器憑證請求。
  2. 利用自建的CA,根據伺服器憑證請求為伺服器簽發伺服器憑證。然後把伺服器憑證導回WEB伺服器中。
  3. 利用openssl產生用戶端(IE)使用的個人數位憑證,也由同樣的CA簽發個人認證。
  4. 將個人數位憑證(PKCS12格式,包含密鑰)匯入到瀏覽器(IE/Firefox)後,就可以進行HTTPS測試了。
 
一. 選擇HTTPS WEB伺服器
這裡我們選擇了Tomcat。當然還有其它方法,如Apache+Tomcat,讓Apache配置成HTTPS模式,而Tomcat只做HTTP業務處理,這樣有利於提高效能,但本文只建造一個簡單的HTTPS測試環境,只用Tomcat內建的HTTPS功能。(當然,我以後會考慮研究一下Apache+Tomcat模式,到時再和大家一起分享經驗)
 
二. 建立一個自己的CA
建立一個自己的CA來類比HTTPS構建環境(利用CA簽發認證),不僅有利於瞭解PKI概念,而且有利於瞭解真正應用的商務程序。關於如何建立一個簡單的測試用CA我已在本部落格發文,題目為《利用openssl建立一個簡單的CA》,請參考http://blog.csdn.net/jasonhwang/archive/2008/04/26/2329589.aspx 這裡就不再重述了。
 
另外,如果你真的覺得建一個CA比較麻煩,且只使用幾個個人數位憑證的話,當然也可以不建CA,下面章節也會提到不用CA如何構建雙向認證。
 
三. 建立伺服器公開金鑰密鑰及頒發伺服器憑證
實際上有兩種方法產生伺服器憑證,一種是用JDK帶的keytool,另一種是用openssl命令產生pkcs12格式的認證。個人更喜歡第二種,因為用openssl產生的pkcs12格式伺服器憑證可以匯出明文的伺服器密鑰,便於用wireshark(ethereal的新名字)查看HTTPS裡被加密過的HTTP訊息。keytool產生的keystore也有辦法匯出密鑰,但還要編程去弄,太麻煩了。
 
方法一,用keytool建立伺服器公開金鑰密鑰並用CA簽發伺服器憑證:
keytool是JDK內建的工具程式,確保keytool已在PATH路徑裡(或在以下命令裡指明keytool的全路徑,如$JAVA_HOME/bin/keytool)。
 
1. 用keytool產生伺服器公開金鑰密鑰:
在TOMCAT的conf目錄裡執行以下命令(假設conf目錄路徑為$TOMCAT_HOME/conf/):
keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias tomcat -genkey -keyalg RSA -dname "CN=servername, OU=servers, O=ABCom"
 
註:其中DN(認證的唯一取別名)裡的CN最好是伺服器的網域名稱地址或IP地址(因為瀏覽器在探索服務器認證的CN與訪問伺服器的網域名稱或IP不符時,會報一個警告,不過這個問題不大)。
 
2. 產生伺服器憑證請求,並讓測試CA簽發伺服器憑證
實際上本步驟也可以省略,唯一不好的結果是使用者在開始訪問伺服器HTTPS服務時,會跳一個視窗警告使用者,使用者可以在該視窗裡看到伺服器憑證是一個自簽名的認證(用伺服器私密金鑰自己給自己簽發的認證,keytool產生公開金鑰密鑰時自動產生這種認證)。但只要使用者選擇“信任該認證”,也照樣可以與伺服器建立HTTPS串連。
但正規的HTTPS伺服器,還是應該申請一個伺服器憑證比較好。
 
2.1 產生伺服器憑證請求:
keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias tomcat -certreq -file serverreq.pem
 
以下命令可以查看一下認證請求的內容:
openssl req -in serverreq.pem -text -noout
 
2.2 用測試CA簽署伺服器憑證:
把serverreq.pem拷貝到CA的某目錄下,我們就可以按照《利用openssl建立一個簡單的CA》裡的“CA的日常操作”的“1. 根據認證申請請求籤發認證”章節進行認證簽發了:
openssl ca -in serverreq.pem -out servercert.pem -config "$HOME/testca/conf/testca.conf"
執行過程中需要輸入CA私密金鑰的保護密碼。
 
2.3 把伺服器憑證導回到伺服器的keystore裡:
前面命令裡產生的servercert.pem即為伺服器憑證。從CA處把該檔案及CA的認證($HOME/testca/cacert.pem)拿來,一起放到Tomcat的conf目錄裡。
另外匯入前,還有一個工作需要做,需要手工編輯servercert.pem認證檔案,把‘-----BEGIN CERTIFICATE-----’該行前的所有內容都刪掉,因為keytool不認得這些說明性的內容。
匯入前也可以執行命令查看一下認證內容:
keytool -printcert -file servercert.pem
 
匯入伺服器憑證:
先匯入CA的認證:
keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias ca -import -trustcacerts -file cacert.pem
 
再匯入伺服器憑證:
keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias tomcat -import -file servercert.pem
 
匯入後可以用以下命令查看一下keystore裡的內容:
keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -list -v
 
3. 建立伺服器信任的用戶端CA認證庫:
用keytool建立一個認證庫,裡面存放伺服器信任的CA認證,也就是只有這些CA簽發的用戶端個人認證才被伺服器信任,才能通過HTTPS訪問伺服器。這就是“HTTPS伺服器驗證用戶端認證”的關鍵配置。註:如果只是測試目的,為了簡單期間,也可以直接把用戶端未經CA簽發的自我簽署憑證直接匯入信任認證庫裡。
 
這裡,我們假設用戶端個人認證(後續章節介紹如何產生用戶端個人認證)也是由測試CA簽發的,所以我們要把cacert.pem認證匯入信任認證庫:
keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -alias ca -import -trustcacerts -file cacert.pem
 
可以用以下命令查看信任認證庫內容:
keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -list -v
 
4. 配置Tomcat支援HTTPS雙向認證(伺服器將認證用戶端認證):
修改tomcat的conf目錄裡的server.xml檔案($TOMCAT_HOME/conf/server.xml),找到類似下面內容的配置處,添加配置如下:
    <Connector port="8443"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" debug="0" scheme="https" secure="true"
               clientAuth="true" sslProtocol="TLS"
               keystoreFile="conf/tomcat.jks" keystorePass="222222" keystoreType="JKS"
      truststoreFile="conf/truststore.jks" truststorePass="222222" truststoreType="JKS" />
 
(題外話:其實HTTPS單向和雙向認證配置的唯一區別是,把clientAuth改為false,去掉truststore的相關配置,就是單向HTTPS認證了,單向HTTPS用的可能更多,它主要在瀏覽器與f伺服器互動的HTTP需要加密,而不需要驗證用戶端認證時使用。)
 
經以上配置後,重啟tomcat,伺服器就支援HTTPS雙向認證了。
 
 
方法二,用openssl建立伺服器公開金鑰密鑰並用CA簽發伺服器憑證:
前面已經提到過,這種方式的好處是有利於抓包查看伺服器與瀏覽器HTTPS互動裡的HTTP資訊。
其實,這種方法與《利用openssl建立一個簡單的CA》裡提到的製作個人數位憑證方法很類似(請參考《利用openssl建立一個簡單的CA》的“三. 自己產生公開金鑰密鑰,並用測試CA簽發數位憑證”章節)。
 
1. 製作伺服器憑證(最終形成一個pkcs12檔案,包含伺服器密鑰、認證和CA的認證)
假設我們把伺服器相關的東西產生到CA的$HOME/testca/test/server目錄裡:
mkdir -p "$HOME/testca/test/server"
cd "$HOME/testca/test/server"
 
2.1 建立伺服器公開金鑰密鑰,並同時產生一個伺服器憑證請求:
openssl req -newkey rsa:1024 -keyout serverkey.pem -keyform PEM -out serverreq.pem /
              -outform PEM  -subj "/O=ABCom/OU=servers/CN=servername"
執行命令過程中輸入密鑰保護密碼222222。
 
執行後可以用以下命令查看請求內容:
openssl req -in serverreq.pem -text -noout
 
2.2 用測試CA簽署伺服器憑證:
把serverreq.pem拷貝到CA的某目錄下,我們就可以按照《利用openssl建立一個簡單的CA》裡的“CA的日常操作”的“1. 根據認證申請請求籤發認證”章節進行認證簽發了:
openssl ca -in serverreq.pem -out servercert.pem -config "$HOME/testca/conf/testca.conf"
執行過程中需要輸入CA私密金鑰的保護密碼。
 
執行完後可以用以下命令查看認證內容:
openssl x509 -in servercert.pem -text -noout
 
2.3 製作伺服器pkcs12檔案(包含伺服器密鑰、認證和CA的認證)
openssl pkcs12 -export -in servercert.pem -inkey serverkey.pem /
                        -out tomcat.p12 -name tomcat -CAfile "$HOME/testca/cacert.pem" /
                        -caname root -chain
執行過程中要輸入伺服器密鑰的保護密碼(serverkey.pem)和新產生的tomcat.p12的保護密碼,我們都輸入222222。
建立完成後,把pkcs12檔案拷貝到tomcat的conf目錄下。
 
3. 建立伺服器信任的用戶端CA認證庫:
同方法一的對應章節,這裡,我們假設用戶端個人認證(後續章節介紹如何產生用戶端個人認證)也是由測試CA簽發的,所以我們要把cacert.pem認證匯入信任認證庫:
keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -alias ca -import -trustcacerts -file cacert.pem
 
可以用以下命令查看信任認證庫內容:
keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -list -v
 
4. 配置Tomcat支援HTTPS雙向認證(伺服器將認證用戶端認證):
修改tomcat的conf目錄裡的server.xml檔案($TOMCAT_HOME/conf/server.xml),找到類似下面內容的配置處,添加配置如下:
    <Connector port="8443"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" debug="0" scheme="https" secure="true"
               clientAuth="true" sslProtocol="TLS"
               keystoreFile="conf/tomcat.p12" keystorePass="222222" keystoreType="PKCS12" 
               truststoreFile="conf/truststore.jks" truststorePass="222222" truststoreType="JKS" />
 
注意:其中keystore的keystoreType與方法一的配置不同。經以上配置後,重啟tomcat,伺服器就支援HTTPS雙向認證了。

四. 建立用於用戶端(瀏覽器)測試的個人數位憑證(pkcs12格式)
完全按照《利用openssl建立一個簡單的CA》裡提到的製作個人數位憑證方法來進行,請參考《利用openssl建立一個簡單的CA》的“三. 自己產生公開金鑰密鑰,並用測試CA簽發數位憑證”章節。
 
1. 建立個人密鑰和認證請求(認證請求裡包含了公開金鑰)
建立$HOME/testuser1目錄並執行命令:(認證等都放到這個目錄)
mkdir $HOME/testuser1
cd $HOME/testuser1
openssl req -newkey rsa:1024 -keyout testkey.pem -keyform PEM -out testreq.pem -outform PEM -subj "/O=TestCom/OU=TestOU/CN=testuser1"
執行過程中需要輸入私密金鑰的保護密碼,假設我們輸入密碼: 222222
 
執行完後,testkey.pem即為使用者的密鑰,而testreq.pem即為認證請求。
可以用openssl req -in testreq.pem -text -noout查看認證請求的內容。
 
2. 用CA為testuser1簽發個人認證
同樣還在$HOME/testuser1目錄下執行命令:
openssl ca -in testreq.pem -out testcert.pem -config "$HOME/testca/conf/testca.conf"
執行過程中需要輸入CA的密鑰保護密碼(剛才設定的888888),並且最後詢問你是否要給該使用者簽發認證時要選y。
執行完後,testcert.pem即為認證,
可以用命令openssl x509 -in testcert.pem -text -noout查看認證內容。
 
3. 製作PKCS12檔案(個人數位憑證)
我們製作的這個PKCS#12檔案將包含密鑰、認證和頒發該認證的CA認證。
把前幾步產生的密鑰和認證製作成一個pkcs12檔案的方法執行命令:
openssl pkcs12 -export -in testcert.pem -inkey testkey.pem -out testuser1.p12 -name testuser1 -chain -CAfile "$HOME/testca/cacert.pem"
執行過程中需要輸入保護密鑰的密碼(222222),以及新的保護pkcs12檔案的密碼(222222)。
 
執行完後,若要查看testuser1.p12的內容可以用命令openssl pkcs12 -in testuser1.p12
該testuser1.p12即為pkcs12檔案。你可以直接拷貝到windows下,作為個人數位憑證,雙擊匯入IE後就可以使用了。
 
五. 用一個簡單webapp來測試HTTPS
伺服器憑證和個人認證都準備好了,我們可以寫一個簡單的webapp,裡面只有一個jsp,用於查看https用戶端驗證是否起效了。
 
1. 建立webapp用於測試https:
在$TOMCAT_HOME/webapps/裡建立一個目錄testhttps,並在testhttps目錄裡建立WEB-INF目錄,並在該目錄裡建立web.xml檔案如下:
檔案:$TOMCAT_HOME/webapps/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <display-name>Test HTTPS App</display-name>
</web-app>
 
2. 建立一個顯示用戶端認證資訊的JSP:
在testhttps目錄建立檔案seecert.jsp
檔案:$TOMCAT_HOME/webapps/WEB-INF/seecert.jsp
<%@ page  import="java.security.cert.X509Certificate" contentType="text/html; charset=GB2312" %>
<pre>
<%
    java.security.cert.X509Certificate[] certs=null;
    try{
            certs=(X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");

                if (certs == null) {
                        out.println("No certificates");
                } else if (certs.length == 0) {
                        out.println("Certificates length is 0");
                } else {
                        java.security.cert.X509Certificate cert = certs[0];
                        String dn = cert.getSubjectX500Principal().toString();
                        out.println("SubjectDN: " + dn);
                        out.println();
                        out.println("------------------certification detail--------------------");
                        out.println(cert);
                        out.println("----------------------------------------------------------");
                }
    } catch(Exception e){
                out.println("Exception=" + e.getMessage());
    }
%>
</pre>
 
3. 測試HTTPS並查看用戶端認證資訊:
訪問URL:https://<tomcat>:8443/testhttps/seecert.jsp
在用瀏覽器訪問該URL時,瀏覽器可能會跳出視窗讓你選擇用哪個用戶端個人認證。
頁面開啟後,你將看到用戶端認證的資訊。
 
六. 使用wireshark(ethereal的新名稱)查看HTTPS裡加密的HTTP訊息:
用wireshark抓包後,你可以看到HTTPS伺服器與瀏覽器之間的HTTPS協商過程,但是HTTPS成功建立後,後續訊息是加密的,如何查看加密的HTTP訊息呢。你需要藉助伺服器的密鑰(私密金鑰)明文。
假設需要從上面提到的openssl產生的伺服器憑證tomcat.p12檔案裡匯出密鑰明文,產生密鑰明文檔案方法:
openssl pkcs12 -in tomcat.p12 -out clearserverkey.pem -nodes
然後在wireshark的協議定義裡找到SSL,並在“RSA keys list”裡配置如下內容:
    <server_ip>,8443,http,<path_to_clearserverkey.pem>
 
其中:
   <server_ip>——為HTTPS伺服器的IP;
   8443——為HTTPS(SSL)的連接埠;
   http——表示SSL裡加密的是HTTP協議;
   <path_to_clearserverkey.pem>——指上一步產生的clearserverkey.pem檔案的本地路徑。
這樣,你就能看到wireshark裡的SSL協議被解密,且裡面的HTTP訊息也看到了。

七. 用戶端認證在Tomcat裡的CRL檢查

請參考《Tomcat裡配置CRL》(http://blog.csdn.net/jasonhwang/archive/2008/05/08/2413310.aspx)。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.