本文將介紹如何利用Tomcat的HTTPS功能,,和一個自己創(chuàng)建的CA,,來構(gòu)建WEB服務(wù)器證書和個人數(shù)字證書,最終建成一個HTTPS雙向認(rèn)證環(huán)境(可以用于測試目的),。本文構(gòu)建HTTPS雙向認(rèn)證的業(yè)務(wù)流程大致如下: 1. 創(chuàng)建WEB服務(wù)器公鑰密鑰,,并生成服務(wù)器證書請求,。 2. 利用自建的CA,根據(jù)服務(wù)器證書請求為服務(wù)器簽發(fā)服務(wù)器證書,。然后把服務(wù)器證書導(dǎo)回WEB服務(wù)器中,。 3. 利用openssl生成客戶端(IE)使用的個人數(shù)字證書,也由同樣的CA簽發(fā)個人證書,。 4. 將個人數(shù)字證書(PKCS12格式,,包含密鑰)導(dǎo)入到瀏覽器(IE/Firefox)后,就可以進(jìn)行HTTPS測試了,。 一. 選擇HTTPS WEB服務(wù)器 這里我們選擇了Tomcat,。當(dāng)然還有其它方法,如Apache+Tomcat,,讓Apache配置成HTTPS模式,,而Tomcat只做HTTP業(yè)務(wù)處理,這樣有利于提高性能,,但本文只建造一個簡單的HTTPS測試環(huán)境,,只用Tomcat自帶的HTTPS功能。(當(dāng)然,,我以后會考慮研究一下Apache+Tomcat模式,,到時再和大家一起分享經(jīng)驗) 二. 創(chuàng)建一個自己的CA 創(chuàng)建一個自己的CA來模擬HTTPS構(gòu)建環(huán)境(利用CA簽發(fā)證書),不僅有利于了解PKI概念,,而且有利于了解真正應(yīng)用的業(yè)務(wù)流程,。關(guān)于如何創(chuàng)建一個簡單的測試用CA我已在本博客發(fā)文,,題目為《利用openssl創(chuàng)建一個簡單的CA》,,請參考http://blog.csdn.net/jasonhwang/archive/2008/04/26/2329589.aspx 這里就不再重述了。 另外,,如果你真的覺得建一個CA比較麻煩,,且只使用幾個個人數(shù)字證書的話,,當(dāng)然也可以不建CA,下面章節(jié)也會提到不用CA如何構(gòu)建雙向認(rèn)證,。 三. 創(chuàng)建服務(wù)器公鑰密鑰及頒發(fā)服務(wù)器證書 實際上有兩種方法生成服務(wù)器證書,,一種是用JDK帶的keytool,另一種是用openssl命令生成pkcs12格式的證書,。個人更喜歡第二種,,因為用openssl生成的pkcs12格式服務(wù)器證書可以導(dǎo)出明文的服務(wù)器密鑰,便于用wireshark(ethereal的新名字)查看HTTPS里被加密過的HTTP消息,。keytool生成的keystore也有辦法導(dǎo)出密鑰,,但還要編程去弄,太麻煩了,。 方法一,,用keytool創(chuàng)建服務(wù)器公鑰密鑰并用CA簽發(fā)服務(wù)器證書: keytool是JDK自帶的工具程序,,確保keytool已在PATH路徑里(或在以下命令里指明keytool的全路徑,如$JAVA_HOME/bin/keytool),。 1. 用keytool生成服務(wù)器公鑰密鑰: 在TOMCAT的conf目錄里執(zhí)行以下命令(假設(shè)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最好是服務(wù)器的域名地址或IP地址(因為瀏覽器在發(fā)現(xiàn)服務(wù)器證書的CN與訪問服務(wù)器的域名或IP不符時,,會報一個警告,不過這個問題不大),。 2. 生成服務(wù)器證書請求,,并讓測試CA簽發(fā)服務(wù)器證書 實際上本步驟也可以省略,唯一不好的結(jié)果是用戶在開始訪問服務(wù)器HTTPS服務(wù)時,,會跳一個窗口警告用戶,,用戶可以在該窗口里看到服務(wù)器證書是一個自簽名的證書(用服務(wù)器私鑰自己給自己簽發(fā)的證書,keytool生成公鑰密鑰時自動生成這種證書),。但只要用戶選擇“信任該證書”,,也照樣可以與服務(wù)器建立HTTPS連接。 但正規(guī)的HTTPS服務(wù)器,,還是應(yīng)該申請一個服務(wù)器證書比較好,。 2.1 生成服務(wù)器證書請求: keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias tomcat -certreq -file serverreq.pem 以下命令可以查看一下證書請求的內(nèi)容: openssl req -in serverreq.pem -text -noout 2.2 用測試CA簽署服務(wù)器證書: 把serverreq.pem拷貝到CA的某目錄下,我們就可以按照《利用openssl創(chuàng)建一個簡單的CA》里的“CA的日常操作”的“1. 根據(jù)證書申請請求簽發(fā)證書”章節(jié)進(jìn)行證書簽發(fā)了: openssl ca -in serverreq.pem -out servercert.pem -config "$HOME/testca/conf/testca.conf" 執(zhí)行過程中需要輸入CA私鑰的保護(hù)密碼,。 2.3 把服務(wù)器證書導(dǎo)回到服務(wù)器的keystore里: 前面命令里生成的servercert.pem即為服務(wù)器證書,。從CA處把該文件及CA的證書($HOME/testca/cacert.pem)拿來,一起放到Tomcat的conf目錄里,。 另外導(dǎo)入前,,還有一個工作需要做,需要手工編輯servercert.pem證書文件,,把‘-----BEGIN CERTIFICATE-----’該行前的所有內(nèi)容都刪掉,因為keytool不認(rèn)得這些說明性的內(nèi)容,。 導(dǎo)入前也可以執(zhí)行命令查看一下證書內(nèi)容: keytool -printcert -file servercert.pem 導(dǎo)入服務(wù)器證書: 先導(dǎo)入CA的證書: keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias ca -import -trustcacerts -file cacert.pem 再導(dǎo)入服務(wù)器證書: keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -alias tomcat -import -file servercert.pem 導(dǎo)入后可以用以下命令查看一下keystore里的內(nèi)容: keytool -keystore tomcat.jks -keypass 222222 -storepass 222222 -list -v 3. 創(chuàng)建服務(wù)器信任的客戶端CA證書庫: 用keytool創(chuàng)建一個證書庫,,里面存放服務(wù)器信任的CA證書,也就是只有這些CA簽發(fā)的客戶端個人證書才被服務(wù)器信任,,才能通過HTTPS訪問服務(wù)器,。這就是“HTTPS服務(wù)器驗證客戶端證書”的關(guān)鍵配置。注:如果只是測試目的,,為了簡單期間,,也可以直接把客戶端未經(jīng)CA簽發(fā)的自簽名證書直接導(dǎo)入信任證書庫里。 這里,,我們假設(shè)客戶端個人證書(后續(xù)章節(jié)介紹如何生成客戶端個人證書)也是由測試CA簽發(fā)的,,所以我們要把cacert.pem證書導(dǎo)入信任證書庫: keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -alias ca -import -trustcacerts -file cacert.pem 可以用以下命令查看信任證書庫內(nèi)容: keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -list -v 4. 配置Tomcat支持HTTPS雙向認(rèn)證(服務(wù)器將認(rèn)證客戶端證書): 修改tomcat的conf目錄里的server.xml文件($TOMCAT_HOME/conf/server.xml),找到類似下面內(nèi)容的配置處,,添加配置如下: <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單向和雙向認(rèn)證配置的唯一區(qū)別是,,把clientAuth改為false,,去掉truststore的相關(guān)配置,就是單向HTTPS認(rèn)證了,,單向HTTPS用的可能更多,,它主要在瀏覽器與f服務(wù)器交互的HTTP需要加密,而不需要驗證客戶端證書時使用,。) 經(jīng)以上配置后,,重啟tomcat,服務(wù)器就支持HTTPS雙向認(rèn)證了,。 方法二,,用openssl創(chuàng)建服務(wù)器公鑰密鑰并用CA簽發(fā)服務(wù)器證書: 前面已經(jīng)提到過,這種方式的好處是有利于抓包查看服務(wù)器與瀏覽器HTTPS交互里的HTTP信息,。 其實,,這種方法與《利用openssl創(chuàng)建一個簡單的CA》里提到的制作個人數(shù)字證書方法很類似(請參考《利用openssl創(chuàng)建一個簡單的CA》的“三. 自己生成公鑰密鑰,并用測試CA簽發(fā)數(shù)字證書”章節(jié)),。 1. 制作服務(wù)器證書(最終形成一個pkcs12文件,,包含服務(wù)器密鑰、證書和CA的證書) 假設(shè)我們把服務(wù)器相關(guān)的東西生成到CA的$HOME/testca/test/server目錄里: mkdir -p "$HOME/testca/test/server" cd "$HOME/testca/test/server" 2.1 創(chuàng)建服務(wù)器公鑰密鑰,,并同時生成一個服務(wù)器證書請求: openssl req -newkey rsa:1024 -keyout serverkey.pem -keyform PEM -out serverreq.pem / -outform PEM -subj "/O=ABCom/OU=servers/CN=servername" 執(zhí)行命令過程中輸入密鑰保護(hù)密碼222222,。 執(zhí)行后可以用以下命令查看請求內(nèi)容: openssl req -in serverreq.pem -text -noout 2.2 用測試CA簽署服務(wù)器證書: 把serverreq.pem拷貝到CA的某目錄下,我們就可以按照《利用openssl創(chuàng)建一個簡單的CA》里的“CA的日常操作”的“1. 根據(jù)證書申請請求簽發(fā)證書”章節(jié)進(jìn)行證書簽發(fā)了: openssl ca -in serverreq.pem -out servercert.pem -config "$HOME/testca/conf/testca.conf" 執(zhí)行過程中需要輸入CA私鑰的保護(hù)密碼,。 執(zhí)行完后可以用以下命令查看證書內(nèi)容: openssl x509 -in servercert.pem -text -noout 2.3 制作服務(wù)器pkcs12文件(包含服務(wù)器密鑰,、證書和CA的證書) openssl pkcs12 -export -in servercert.pem -inkey serverkey.pem / -out tomcat.p12 -name tomcat -CAfile "$HOME/testca/cacert.pem" / -caname root -chain 執(zhí)行過程中要輸入服務(wù)器密鑰的保護(hù)密碼(serverkey.pem)和新生成的tomcat.p12的保護(hù)密碼,我們都輸入222222,。 創(chuàng)建完成后,,把pkcs12文件拷貝到tomcat的conf目錄下。 3. 創(chuàng)建服務(wù)器信任的客戶端CA證書庫: 同方法一的對應(yīng)章節(jié),,這里,,我們假設(shè)客戶端個人證書(后續(xù)章節(jié)介紹如何生成客戶端個人證書)也是由測試CA簽發(fā)的,所以我們要把cacert.pem證書導(dǎo)入信任證書庫: keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -alias ca -import -trustcacerts -file cacert.pem 可以用以下命令查看信任證書庫內(nèi)容: keytool -keystore truststore.jks -keypass 222222 -storepass 222222 -list -v 4. 配置Tomcat支持HTTPS雙向認(rèn)證(服務(wù)器將認(rèn)證客戶端證書): 修改tomcat的conf目錄里的server.xml文件($TOMCAT_HOME/conf/server.xml),,找到類似下面內(nèi)容的配置處,,添加配置如下: <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與方法一的配置不同。經(jīng)以上配置后,,重啟tomcat,,服務(wù)器就支持HTTPS雙向認(rèn)證了。
四. 創(chuàng)建用于客戶端(瀏覽器)測試的個人數(shù)字證書(pkcs12格式) 完全按照《利用openssl創(chuàng)建一個簡單的CA》里提到的制作個人數(shù)字證書方法來進(jìn)行,,請參考《利用openssl創(chuàng)建一個簡單的CA》的“三. 自己生成公鑰密鑰,,并用測試CA簽發(fā)數(shù)字證書”章節(jié)。 1. 創(chuàng)建個人密鑰和證書請求(證書請求里包含了公鑰) 創(chuàng)建$HOME/testuser1目錄并執(zhí)行命令:(證書等都放到這個目錄) 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" 執(zhí)行過程中需要輸入私鑰的保護(hù)密碼,假設(shè)我們輸入密碼: 222222 執(zhí)行完后,,testkey.pem即為用戶的密鑰,,而testreq.pem即為證書請求。 可以用openssl req -in testreq.pem -text -noout查看證書請求的內(nèi)容,。 2. 用CA為testuser1簽發(fā)個人證書 同樣還在$HOME/testuser1目錄下執(zhí)行命令: openssl ca -in testreq.pem -out testcert.pem -config "$HOME/testca/conf/testca.conf" 執(zhí)行過程中需要輸入CA的密鑰保護(hù)密碼(剛才設(shè)置的888888),,并且最后詢問你是否要給該用戶簽發(fā)證書時要選y。 執(zhí)行完后,,testcert.pem即為證書,, 可以用命令openssl x509 -in testcert.pem -text -noout查看證書內(nèi)容。 3. 制作PKCS12文件(個人數(shù)字證書) 我們制作的這個PKCS#12文件將包含密鑰,、證書和頒發(fā)該證書的CA證書,。 把前幾步生成的密鑰和證書制作成一個pkcs12文件的方法執(zhí)行命令: openssl pkcs12 -export -in testcert.pem -inkey testkey.pem -out testuser1.p12 -name testuser1 -chain -CAfile "$HOME/testca/cacert.pem" 執(zhí)行過程中需要輸入保護(hù)密鑰的密碼(222222),以及新的保護(hù)pkcs12文件的密碼(222222),。 執(zhí)行完后,,若要查看testuser1.p12的內(nèi)容可以用命令openssl pkcs12 -in testuser1.p12 該testuser1.p12即為pkcs12文件。你可以直接拷貝到windows下,,作為個人數(shù)字證書,,雙擊導(dǎo)入IE后就可以使用了。 五. 用一個簡單webapp來測試HTTPS 服務(wù)器證書和個人證書都準(zhǔn)備好了,,我們可以寫一個簡單的webapp,,里面只有一個jsp,用于查看https客戶端驗證是否起效了,。 1. 創(chuàng)建webapp用于測試https: 在$TOMCAT_HOME/webapps/里創(chuàng)建一個目錄testhttps,,并在testhttps目錄里創(chuàng)建WEB-INF目錄,并在該目錄里創(chuàng)建web.xml文件如下: 文件:$TOMCAT_HOME/webapps/WEB-INF/web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java./xml/ns/j2ee" xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:schemaLocation="http://java./xml/ns/j2ee http://java./xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>Test HTTPS App</display-name> </web-app> 2. 創(chuàng)建一個顯示客戶端證書信息的JSP: 在testhttps目錄創(chuàng)建文件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服務(wù)器與瀏覽器之間的HTTPS協(xié)商過程,但是HTTPS成功建立后,,后續(xù)消息是加密的,如何查看加密的HTTP消息呢,?你需要借助服務(wù)器的密鑰(私鑰)明文,。 假設(shè)需要從上面提到的openssl生成的服務(wù)器證書tomcat.p12文件里導(dǎo)出密鑰明文,生成密鑰明文文件方法: openssl pkcs12 -in tomcat.p12 -out clearserverkey.pem -nodes 然后在wireshark的協(xié)議定義里找到SSL,,并在“RSA keys list”里配置如下內(nèi)容: <server_ip>,8443,http,<path_to_clearserverkey.pem> 其中: <server_ip>——為HTTPS服務(wù)器的IP,; 8443——為HTTPS(SSL)的端口; http——表示SSL里加密的是HTTP協(xié)議; <path_to_clearserverkey.pem>——指上一步生成的clearserverkey.pem文件的本地路徑,。 這樣,,你就能看到wireshark里的SSL協(xié)議被解密,且里面的HTTP消息也看到了,。
七. 客戶端證書在Tomcat里的CRL檢查
請參考《Tomcat里配置CRL》(http://blog.csdn.net/jasonhwang/archive/2008/05/08/2413310.aspx),。
|