Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat fails with UnrecoverableKeyException: Cannot recover key

Tags:

java

tomcat

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.

like image 385
Søren Boisen Avatar asked Sep 14 '25 18:09

Søren Boisen


1 Answers

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!

like image 59
Søren Boisen Avatar answered Sep 16 '25 08:09

Søren Boisen