Caused by: java.security.UnrecoverableKeyException: Cannot recover key

JavaSslSsl CertificateJks

Java Problem Overview


I am supplied with a jks keystore named ABCC_client.store. When I import this keystore to cacerts and try connecting it says No such Algorithm error. PFA the stacktrace

    Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class:   com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
	at java.security.Provider$Service.newInstance(Provider.java:1245)
	at sun.security.jca.GetInstance.getInstance(GetInstance.java:220)
	at sun.security.jca.GetInstance.getInstance(GetInstance.java:147)
	at javax.net.ssl.SSLContext.getInstance(SSLContext.java:125)
	at javax.net.ssl.SSLContext.getDefault(SSLContext.java:68)
	at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:102)
	at org.apache.axis.components.net.JSSESocketFactory.initFactory(JSSESocketFactory.java:61)
	at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:79)
	... 32 more
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
	at sun.security.provider.KeyProtector.recover(KeyProtector.java:311)
	at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:121)
	at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:38)
	at java.security.KeyStore.getKey(KeyStore.java:763)
	at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:113)
	at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:48)
	at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:239)
	at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.getDefaultKeyManager(DefaultSSLContextImpl.java:170)
	at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.<init>(DefaultSSLContextImpl.java:40)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at java.security.Provider$Service.newInstance(Provider.java:1221)
	... 39 more

But if I use this keystore independently i.e without adding it to cacerts it works.

Some googling led to me to http://joewlarson.com/blog/2009/03/25/java-ssl-use-the-same-password-for-keystore-and-key/ which says that password might me different for the key and the keystore.

Java Solutions


Solution 1 - Java

If using Tomcat 6 and earlier, make sure the keystore password and the key password are same. If using Tomcat 7 and later, make sure they are the same or that the key password is specified in the server.xml file.

Solution 2 - Java

The private key password defined in your app/config is incorrect. First try verifying the the private key password by changing to another one as follows:

keytool -keypasswd -new changeit -keystore cacerts -storepass changeit -alias someapp -keypass password

The above example changes the password from password to changeit. This command will succeed if the private key password was password.

Solution 3 - Java

In order to not have the Cannot recover key exception, I had to apply the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files to the installation of Java that was running my application. Version 8 of those files can be found here or the latest version should be listed on this page. The download includes a file that explains how to apply the policy files.


Since JDK 8u151 it isn't necessary to add policy files. Instead the JCE jurisdiction policy files are controlled by a Security property called crypto.policy. Setting that to unlimited with allow unlimited cryptography to be used by the JDK. As the release notes linked to above state, it can be set by Security.setProperty() or via the java.security file. The java.security file could also be appended to by adding -Djava.security.properties=my_security.properties to the command to start the program as detailed here.


Since JDK 8u161 unlimited cryptography is enabled by default.

Solution 4 - Java

I had the same error when we imported a key into a keystore that was build using a 64bit OpenSSL Version. When we followed the same procedure to import the key into a keystore that was build using a 32 bit OpenSSL version everything went fine.

Solution 5 - Java

Check if password you are using is correct one by running below command

keytool -keypasswd -new temp123 -keystore awsdemo-keystore.jks -storepass temp123 -alias movie-service -keypass changeit

If you are getting below error then your password is wrong

keytool error: java.security.UnrecoverableKeyException: Cannot recover key

Solution 6 - Java

Sometimes this seems to be happening for no reason. I too faced the same and tried all methods like Keytool explorer etc.

Ultimately ended requesting Google to reset the key since I had Google play signing enabled. This is a good recommendation to follow.

https://support.google.com/googleplay/android-developer/answer/9842756?hl=en

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMrinal BhattacharjeeView Question on Stackoverflow
Solution 1 - Javauser805125View Answer on Stackoverflow
Solution 2 - JavaUmesh RajbhandariView Answer on Stackoverflow
Solution 3 - JavaWhiteKnightView Answer on Stackoverflow
Solution 4 - JavaHeimiView Answer on Stackoverflow
Solution 5 - JavaRobin MathurView Answer on Stackoverflow
Solution 6 - JavaRavi SethiaView Answer on Stackoverflow