配置SSL证书后Tomcat启动失败,求技术解决方案
问题描述
我在配置SSL证书后启动Tomcat服务器时遇到以下错误:
30-Jan-2018 07:04:54.821 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8443"]
30-Jan-2018 07:04:55.157 SEVERE [main] org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-nio-8443"] 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:1914)
at java.security.KeyStore.load(KeyStore.java:1445)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:424)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:323)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:581)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:521)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:357)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:732)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:457)
at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:567)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:851)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.startup.Catalina.load(Catalina.java:576)
at org.apache.catalina.startup.Catalina.load(Catalina.java:599)
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:497)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:310)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:484)
30-Jan-2018 07:04:55.159 SEVERE [main] 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:567)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:851)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
我持有一份.pfx证书,创建了keystore并导入该证书,随后在server.xml中配置了连接器使用此keystore,但启动时出现上述错误,请问问题出在哪里?
问题诊断与解决方案
这个错误大概率是因为你把PFX证书的使用方式搞错了——PFX本身就是PKCS#12格式的密钥库,不需要额外导入到JKS密钥库中,直接用就行。如果强行导入操作步骤出错,就会出现这种解析错误。
下面是具体的解决方法:
1. 直接使用PFX证书(推荐)
Tomcat原生支持PKCS#12格式的证书文件,直接修改server.xml里的Connector配置即可:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="/绝对路径/你的证书文件.pfx" certificateKeystoreType="PKCS12" certificateKeystorePassword="你的PFX密码" /> </SSLHostConfig> </Connector>
注意替换路径、密码为你自己的实际信息,路径尽量用绝对路径,避免Tomcat找不到文件。
2. 若一定要导入到JKS(不推荐)
如果坚持要把PFX转成JKS格式,确保用正确的keytool命令:
keytool -importkeystore -srckeystore your-cert.pfx -srcstoretype PKCS12 -destkeystore your-jks-store.jks -deststoretype JKS
执行时会先要求输入PFX的源密码,再设置JKS的目标密码。完成后在server.xml里配置JKS的路径和密码即可。
3. 排查常见坑点
- 检查证书路径:确保
certificateKeystoreFile的路径正确,Tomcat进程有读取该文件的权限 - 验证PFX有效性:用以下命令查看证书详情,确认文件没损坏、密码正确
keytool -list -v -storetype pkcs12 -keystore your-cert.pfx - 检查
server.xml配置:确认没有拼写错误,比如PKCS12的大小写,密码是否和证书一致
内容的提问来源于stack exchange,提问作者Peyush Goel

