tomcat7.0.55配置单向和双向HTTPS连接(二)
上一篇文章: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
然后导入浏览器即可,这样就不用修改服务器的配置文件重启服务器了