102

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.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Mrinal Bhattacharjee
  • 1,326
  • 4
  • 10
  • 15
  • A bit of code to see what's called if possible? – Bruno Apr 12 '13 at 09:34
  • i was trying to call a web service method from within the code..AxisFault faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException faultSubcode: faultString: java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl) – Mrinal Bhattacharjee Apr 12 '13 at 09:49
  • 2
    May be duplicated here is a similar [question](http://stackoverflow.com/questions/1321557/can-not-get-key-from-keystore) with an asnwer. – icrovett Apr 12 '13 at 09:55
  • No My issue is the keystore works if we set the system properties to use that keystore. But If we load that keystore into jvm's default i.e cacerts it doest wrk. It says bad certificate.. – Mrinal Bhattacharjee Apr 16 '13 at 09:56
  • in my case i was provided a wrong password. – nikhil2000 May 18 '23 at 08:05

6 Answers6

135

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.

Captain Man
  • 6,997
  • 6
  • 48
  • 74
  • 10
    This is true. Reference https://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html#Prepare_the_Certificate_Keystore – Atharva Sep 13 '15 at 07:21
  • 2
    Relevant quote: Finally, you will be prompted for the *key password*, which is the password specifically for this Certificate (as opposed to any other Certificates stored in the same keystore file). You **MUST** use the same password here as was used for the keystore password itself. This is a restriction of the Tomcat implementation. (Currently, the `keytool` prompt will tell you that pressing the ENTER key does this for you automatically.) – Captain Man May 02 '17 at 18:54
  • I had this issue w JMeter (https) coz Java keystore and key passwords were different. Ref https://stackoverflow.com/questions/2889238/keystore-change-passwords?noredirect=1&lq=1 . to change the key password to solve the issue. Great help! Thanks. – Rishi Nov 18 '17 at 00:50
  • @CaptainMan that's only true in Tomcat6, from Tomcat7 [it is not](https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Prepare_the_Certificate_Keystore). – Andrea Ligios Mar 02 '18 at 09:23
  • 2
    @AndreaLigios good point, relevant quote: Finally, you will be prompted for the *key password*, which is the password specifically for this Certificate (as opposed to any other Certificates stored in the same keystore file). The `keytool` prompt will tell you that pressing the ENTER key automatically uses the same password for the key as the keystore. You are free to use the same password or to select a custom one. **If you select a different password to the keystore password, you will also need to specify the custom password in the `server.xml` configuration file.** – Captain Man Mar 02 '18 at 18:04
  • Still an issue in Tomcat 8 – sweetfa Jul 04 '18 at 08:13
  • Same for Jetty. – user11153 Mar 19 '21 at 11:58
81

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.

Les Hazlewood
  • 18,480
  • 13
  • 68
  • 76
Umesh Rajbhandari
  • 1,222
  • 9
  • 9
  • 3
    While I didn't use this answer in relation to the question. It was helpful for validating a keystore file, store password, alias/key, and key password. – Russ Feb 10 '14 at 23:42
  • 1
    Please remember that after executing this command you will change the keystore password. You would have to set the password back to the original one. – gersonZaragocin Jul 28 '16 at 16:08
  • actually, it's enough to specify just `-keypasswd -keystore storefile -alias somealias` and enter everything else in a prompt. – Andrey Regentov Oct 25 '16 at 07:48
  • 1
    On running this code I am getting the following error - `"keytool error: java.security.UnrecoverableKeyException: Cannot recover key"` Is there any way to check what is my alias key password or change it without knowing the old one? – Kavin Raju S Dec 24 '18 at 02:35
10

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.

Community
  • 1
  • 1
WhiteKnight
  • 4,938
  • 5
  • 37
  • 41
  • 3
    I am seeing this error despite having the policy file jars installed. – Adam Jan 16 '18 at 12:18
  • @Adam My solution is for a specific case, which may be different to the one you are experiencing. However I've added an update to reflect the change that occurred in JDK 8u151. – WhiteKnight Jan 16 '18 at 13:10
5

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.

Heimi
  • 51
  • 1
  • 3
  • 4
    The root cause of the Error above was java.security.UnrecoverableKeyException: Cannot recover key. The reason for that can be a false password as mentioned above, but also a keystore build with a 64bit OpenSSL Implementation. So I consider my Answer as another possible solution. It helped me in the same error situation, so I provided the solution here. – Heimi Dec 29 '15 at 14:45
  • openssl doesn't create Java keystore files. Could you clarify this? – aled Mar 31 '16 at 20:40
  • Thks for you answer. I face the same problem when invoking https webservices form OpenESB 3.05. I follow your instructions and generate the jks file again with a 32bit implementation of OpenSS and it works fine – Marti Pàmies Solà Jan 11 '18 at 09:14
5

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
Robin Mathur
  • 447
  • 5
  • 4
  • 6
    If I use any other password I receive error `Keystore was tampered with, or password was incorrect`. If I use password I know its correct I get error `Cannot recover key`. So I don't think your statement is correct, at least in my case. Something else might cause the error – Alexandru Severin Mar 04 '21 at 09:04
  • Tomcat can cause this issue when the keyAlias parameter is missing or the value is not matches the alias name in the keystore. Ensure you're using the correct alias by issuing `keytool -list -keystore something.jks -storepass temp123` and checking the alias in the listing. – Gabor Garami Nov 26 '21 at 16:10
0

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

Ravi Sethia
  • 85
  • 2
  • 9