Reputation: 1706
I have Apache Tomcat/7.0.68 running on a server, and I'm trying to automate certificate renewal for it.
The certificate along with private key is imported via Java's keytool from a PKCS#12 file (excerpt from Powershell script):
& $keytool -importkeystore -srckeystore $certfile -srcstoretype PKCS12 -srcstorepass $srcpassword -srcalias tomcat -keystore $keystore -deststorepass $dstpassword -destalias teamcity -destkeypass $dstpassword -noprompt
When I restart Tomcat, it spits out the following log lines:
INFO: Initializing ProtocolHandler ["http-nio-443"]
jul. 14, 2017 5:03:31 PM org.apache.coyote.AbstractProtocol init
SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-nio-443"]
java.security.UnrecoverableKeyException: Cannot recover key
at sun.security.provider.KeyProtector.recover(KeyProtector.java:328)
at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:146)
at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:56)
at sun.security.provider.KeyStoreDelegator.engineGetKey(KeyStoreDelegator.java:96)
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineGetKey(JavaKeyStore.java:70)
at java.security.KeyStore.getKey(KeyStore.java:1023)
at sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:133)
at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:608)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:537)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:495)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:650)
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:560)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:820)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.startup.Catalina.load(Catalina.java:642)
at org.apache.catalina.startup.Catalina.load(Catalina.java:667)
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:253)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:427)
But when I try to change the password via keytool, it can read the entry fine and change password.
PS: I made sure the password for the entry was the same as for the store, since at least some versions of Tomcat needed this.
Upvotes: 4
Views: 9675
Reputation: 1706
Finally solved it. It turns out that having a completely unrelated key in the keystore with a different password than the keystore breaks Tomcat as detailed in this ancient bug report!
Upvotes: 6