上一篇文章:tomcat7.0.55配置單向和雙向HTTPS連接
只是簡要的配置了一下HTTPS,還有許多問題沒有解決,本篇來解決這些文件
首先按照這篇文章:Widows下利用OpenSSL生成證書來生成證書,由於tomcat7目前只支持JKS、PKCS11、PKCS12密鑰存儲庫,下面我們把得到的證書轉換成這幾種格式
將CA公鑰存到信任密鑰庫
keytool -import -file keys\ca.crt -alias firstCA -keystore keys\myTrustStore
服務器證書轉為PKCS12格式
openssl pkcs12 -export -in keys\server.crt -inkey keys\server.key -certfile keys\ca.crt -out keys\server.p12
客戶端證書轉為PKCS12格式
openssl pkcs12 -export -in keys\client.crt -inkey keys\client.key -certfile keys\ca.crt -out keys\client.p12
上面我們得到3個文件:信任庫文件myTrustStore、服務器密鑰庫文件server.p12、客戶端密鑰庫文件client.p12
配置單向連接
將server.p12復制到tomcat的conf目錄下
修改server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="conf/server.p12" keystoreType="PKCS12" keystorePass="12345678" />
啟動tomcat
瀏覽器導入ca.crt(證書存儲區域為受信任的根證書),然后訪問https://localhost:8443/
配置雙向連接
將server.p12、myTrustStore復制到tomcat的conf目錄下
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" keystoreFile="conf/server.p12" keystoreType="PKCS12" keystorePass="12345678" truststoreFile="conf/myTrustStore" truststoreType="JKS" truststorePass="12345678" />
啟動tomcat
瀏覽器導入ca.crt(證書存儲區域為受信任的根證書)、client.p12(證書存儲區域為個人),然后訪問https://localhost:8443/
這里雙向配置還有一個要注意的問題,如果truststoreType參數不配置,默認情況下是與keystoreType參數保持一致,不一定是JKS,筆者調了很久才發現錯在這里。所以類型不一致時,兩個參數最好都配上,以免出現問題。
筆者報的異常
java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. at sun.security.util.DerInputStream.getLength(DerInputStream.java:561) at sun.security.util.DerValue.init(DerValue.java:365) at sun.security.util.DerValue.<init>(DerValue.java:320) at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1872) at java.security.KeyStore.load(KeyStore.java:1433) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:392) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustStore(JSSESocketFactory.java:343) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustManagers(JSSESocketFactory.java:599) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustManagers(JSSESocketFactory.java:511) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:434) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:181) at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:398) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:646) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:434) at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119) at org.apache.catalina.connector.Connector.initInternal(Connector.java:978) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:821) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102) at org.apache.catalina.startup.Catalina.load(Catalina.java:638) at org.apache.catalina.startup.Catalina.load(Catalina.java:663) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:280) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:454) 五月 13, 2015 4:56:34 下午 org.apache.catalina.core.StandardService initInternal 嚴重: Failed to initialize connector [Connector[HTTP/1.1-8443]] org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]] at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:821) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102) at org.apache.catalina.startup.Catalina.load(Catalina.java:638) at org.apache.catalina.startup.Catalina.load(Catalina.java:663) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:280) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:454) Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:980) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102) ... 12 more Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. at sun.security.util.DerInputStream.getLength(DerInputStream.java:561) at sun.security.util.DerValue.init(DerValue.java:365) at sun.security.util.DerValue.<init>(DerValue.java:320) at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1872) at java.security.KeyStore.load(KeyStore.java:1433) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:392) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustStore(JSSESocketFactory.java:343) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustManagers(JSSESocketFactory.java:599) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustManagers(JSSESocketFactory.java:511) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:434) at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:181) at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:398) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:646) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:434) at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119) at org.apache.catalina.connector.Connector.initInternal(Connector.java:978) ... 13 more
加上truststoreType參數之后恢復正常。
官方解釋
The type of key store used for the trust store. The default is the value of the javax.net.ssl.trustStoreType system property. If that property is null, the value of keystoreType is used as the default.
補充:PKCS12與JKS證書轉換命令
pkcs12轉換成JKS
keytool -importkeystore -v -srckeystore server.p12 -srcstoretype pkcs12 -srcstorepass 12345678 -destkeystore server.keystore -deststoretype jks -deststorepass 12345678
JKS轉換成pkcs12
keytool -importkeystore -v -srckeystore server.keystore -srcstoretype jks -srcstorepass 12345678 -destkeystore server.p12 -deststoretype pkcs12 -deststorepass 12345678
如果需要增加客戶端證書,需要進行如下操作
設置環境變量
SET HOME=.
SET KEY_DIR=keys
生成證書並簽名
openssl req -days 3650 -nodes -new -keyout keys\client2.key -out keys\client2.csr -config openssl-1.0.2a.cnf
openssl ca -days 3650 -out keys\client2.crt -in keys\client2.csr -config openssl-1.0.2a.cnf
del /q keys\*.old
證書轉換為PKCS12格式
openssl pkcs12 -export -in keys\client2.crt -inkey keys\client2.key -certfile keys\ca.crt -out keys\client2.p12
然后導入瀏覽器即可,這樣就不用修改服務器的配置文件重啟服務器了