配置適用于正式使用環境下的Tomcat Web服務器雙向SSL認證
關于如何使用Tomcat服務器實現雙向SSL認證的文章很早就有了, 比較實用的文章可以看看
IBM developerWorks 中國網站 2002年5月 配置Tomcat 4使用SSL(
http://www-900.ibm.com/developerWorks/cn/security/se-tcssl/index.shtml ), 使用 google 還可以搜索到很多類似的文章.
但
是現在看來, 這些文章也有不足之處, 一是只說明了在 Tomcat 4 服務器上的配置方法, 與現在普遍使用的 Tomcat 5
系列的配置方法有一定的差異, 其次, 這些文章中的方法大多是作為一種實驗性的操作介紹, 如果用于實際Web服務器的產生證書環境,
還是會存在一些問題的:
- 生成的CA私鑰(ca-key.pem)以及自簽名根證書(ca-cert.pem)均為沒有加密的明文, 由于一旦在服務器發布,
以及客戶端證書發布之后, 根證書是不能隨便修改的,
那么在保管沒有加密的CA私鑰以及自簽名根證書時就會存在安全性問題(如果別人得到你的CA根證書, 他就可以替你生成客戶端證書了);
- 生成的服務器端證書(server_keystore)不包括信任的CA根證書,
信任的CA根證書被導入到JSSE的默認位置, 如果進行證書操作的計算機和真正運行Web應用的不是同一臺計算機, 那么在安裝服務器端證書的時候,
還需要在服務器上將CA根證書導入JSSE默認位置;
- 生成客戶端證書的過程比較煩瑣, 不方便批量進行客戶端證書的生成;
- 沒有統一的配置文件, 生成證書的過程中需要執行相當多的命令, 可重復性差, 出錯的可能性比較大.
針對以上的問題, 在參考"配置Tomcat 4使用SSL"這篇文章的基礎上, 整理出由4個批處理命令和一個配置文件組成的證書工具包, 這個工具包考慮到在實際Web服務器環境下產生證書的需求, 克服了上面提到的那些問題.
用到的軟件包
- Tomcat 5.0.x
- JSSE 中的 keytool 工具, 在 JDK 1.4 中已經自帶了這個工具, 因此, 只需要安裝 JDK1.4.x 即可
- openssl(openssl 已經被包含在這個工具包里面了, 不需要另外安裝, 參見工具包下載)
- cygwin 的 sed 和 echo 命令(這些命令文件已經包含在工具包里面, 不需要另外安裝, 參見工具包下載)
配置及主要命令介紹
- PATH 環境變量
- 安裝 JDK 之后, 需要將環境變量 JAVA_HOME 設置為 JDK 的安裝目錄, 同時在 PATH 中加上 %JAVA_HOME%"bin.
- 工具包結構
- .bin: 存放openssl 以及 cygwin 的 sed 和 echo 命令的可執行執行文件;
- .etc: 存放系統的配置文件, 其中最主要的配置文件是 .etc/config.cmd;
- dist: 這個目錄存放產生的各種證書;
- work: 產生證書時使用的臨時文件的存放目錄, 為了安全起見, 在每次證書相關操作結束后, 建議清空這個目錄;
- step0,1,2,3 四個批處理命令: 這四個命令分別用于證書各個方面的操作.
- .etc/config.cmd
- 這個文件是系統的配置文件, 主要配置 CA根證書/服務器證書/客戶端證書 的相關信息, 例如證書的distinguished name信息等等, 在生成證書之前, 需要首先根據實際情況更新這個配置文件;
- step0-ca-pfx.bat
- 該命令生成CA私鑰以及自簽名根證書, 最后得到PKCS12格式的CA根證書(PKCS12格式的CA根證書受密碼保護, 因此有比較好的安全性);
- 生成的PKCS12格式的CA根證書保存在 dist"ca-cert 目錄下, 在正式使用的系統中,
這個證書文件(*.pfx)需要妥善保存, 因為以后的服務器證書和客戶端證書都需要依賴這個證書, 尤其是客戶端證書, 如果丟失了CA根證書,
就無法發布新的客戶端證書了, 而重新生成CA根證書, 則需要重新生成服務器證書和客戶端證書, 在客戶端用戶較多的情況下,
重新發布所有的客戶端證書是有相當大的工作量;
- 在執行這個命令的過程中, 會提示輸入證書保護密碼, 請注意不要遺忘或者泄漏這個密碼, 否則根證書的安全會受到威脅.
- step1-ca-prepare.bat
- 該命令用于從PKCS12格式的CA根證書中導出CA私鑰和未加密CA根證書;
- 由于安全原因, CA根證書平時以密碼保護的PKCS12格式文件(*.pfx)存放, 那么如果需要使用CA根證書來發布服務器證書或者客戶端證書時, 首先需要執行這個命令得到CA根證書的未加密形式;
- 在執行這個命令的過程中, 會出現兩次提示輸入根證書的保護密碼, 如果密碼不正確, 這個命令將不能執行成功, 也就無法進行下面兩步的發布證書的操作了.
- step2-server.bat
- 該命令用于生成服務器端證書(keystore文件);
- 注意: CA根證書同時也會被導入到證書的keystore文件中, 這樣在將這個證書應用到Tomcat Web服務器上的時候就不需要將CA根證書導入到JSSE的默認位置了;
- 這個命令必須在執行 step1-ca-prepare.bat 之后才能正常運行.
- step3-client.bat
- 這個命令用于發布客戶端證書;
- 為了便于批量生成客戶端證書, 這個命令支持命令行參數, 第1到3個參數依次為:
- 客戶端證書的名稱(Common Name)
- 客戶端證書所屬的組織(Organizational Unit Name)
- 產生的PKS12格式客戶端證書的導入密碼, 這個密碼可以保護證書只能被知道密碼的用戶導入到瀏覽器
- 這個命令必須在執行 step1-ca-prepare.bat 之后才能正常運行.
說明:當Web
服務器開始正式運行以后, step0-ca-pfx.bat 命令是不能再次執行的, 如果需要重新發布服務器證書, 或者發布新的客戶端證書,
在執行 step2-server.bat 和 step3-client.bat 命令前, 可以通過 step1-ca-prepare.bat
重新從保存的PKCS12格式CA根證書中導出CA私鑰和未加密CA根證書.
Tomcat 5 服務器配置
參考配置方法如下:
- 將 "step2-server.bat" 命令產生的 dist"server 目錄下的 keystore
文件(如果使用本工具包的默認配置, 這個文件叫做"ssl-test.net-tomcat.keystore")復制到 Tomcat 安裝目錄的
conf 目錄下;
- 修改 Tomcat 安裝目錄的 conf 目錄下的 "server.xml" 文件, 修改 <Service name="Catalina"> 包含的 "Connector" 元素, 示例如下(僅供參考):
<Service name="Catalina">
<Connector URIEncoding="UTF-8"
acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"
port="8080" redirectPort="8443"
maxSpareThreads="75" maxThreads="150" minSpareThreads="25">
</Connector>
<Connector URIEncoding="UTF-8" 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="${catalina.home}/conf/ssl-test.net-tomcat.keystore"
keystorePass="openssl"
truststoreFile="${catalina.home}/conf/ssl-test.net-tomcat.keystore"
truststorePass="openssl"/>
......
啟用雙向 SSL 時 Web 應用程序的配置
- 要啟用雙向 SSL 認證, 在 Web 應用程序的 web.xml 中需要如下增加一些配置:
auth-method=CLIENT-CERT
說明是"以客戶端數字證書來確認用戶的身份", transport-guarantee=CONFIDENTIAL
表示應用程序要求數據必須在一種"防止其他實體看到傳輸的內容的方式中傳送".
<login-config>
<!-- Authorization setting for SSL -->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<!-- Authorization setting for SSL -->
<web-resource-collection >
<web-resource-name >SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
- 經過以上的配置之后, 那么即使用戶是通過 http 訪問 Web 應用程序的, 瀏覽器也會自動切換到 https 方式并彈出選擇客戶端證書的對話框.
如何使用客戶端證書進行用戶驗證
- 查看一些資料上提到客戶端證書內容中 subject 的 CN 部分可以和 Tomcat 的 Realm 中的用戶集成, 不過一直沒有嘗試成功;
- 在 web 應用程序中, 可以通過 java 代碼從 request 對象中獲得, 根據 Servlet Specifications, 使用
request.getAttribute("javax.servlet.request.X509Certificate")
就可以得到 https 請求的客戶端證書鏈信息, 其中第一個元素就是客戶端證書, 相應的示例代碼如下:
String certSubject = null;
X509Certificate[] certChain=
(X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
int len=certChain.length;
if (len>0){
X509Certificate cert = (X509Certificate)certChain[0];
Principal pSubject = cert.getSubjectDN();
certSubject = pSubject.getName();
} |
- 客戶端證書的 subject 是類似
CN=client, OU=web, O=ssl-test.net, L=your_locality, ST=your_province, C=CN
這樣的字符串, 其中 CN=... 就是客戶端證書的用戶名稱, Web 應用程序可以通過這個字段來驗證 https 請求對應的用戶身份了.
工具包下載
運行界面(使用 Mozilla Firefox 1.0)
- 沒有安裝證書時訪問 Web 應用程序被服務器拒絕
- 訪問 Web 應用程序時提示選擇證書的對話框

比較復雜的問題, 請到 Tomcat5SSL_ServerAndClient 常見問題 頁面討論.
例子請看