Auslöser: java.security.UnrecoverableKeyException: Schlüssel kann nicht wiederhergestellt werden

84

Ich werde mit einem jks-Keystore namens ABCC_client.store geliefert. Wenn ich diesen Schlüsselspeicher in cacerts importiere und versuche, ihn zu verbinden, wird "Kein solcher Algorithmusfehler" angezeigt. PFA die Stapelverfolgung

    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

Aber wenn ich diesen Keystore unabhängig verwende, dh ohne ihn zu cacerts hinzuzufügen, funktioniert er.

Ein bisschen googeln führte mich zu http://joewlarson.com/blog/2009/03/25/java-ssl-use-the-same-password-for-keystore-and-key/, wo steht, dass das Passwort für mich anders sein könnte der Schlüssel und der Schlüsselspeicher.

Mrinal Bhattacharjee
quelle
Ein bisschen Code, um zu sehen, wie es heißt, wenn möglich?
Bruno
ich versuchte , einen Web - Service - Methode aufrufen , aus dem code..AxisFault faultCode: { schemas.xmlsoap.org/soap/envelope } Server.userException faultSubcode: faultString: java.net.SocketException: java.security.NoSuchAlgorithmException: Fehler Konstruieren Implementierung (Algorithmus: Standard, Anbieter: SunJSSE, Klasse: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Mrinal Bhattacharjee
2
Kann hier dupliziert werden, ist eine ähnliche Frage mit einer Antwort.
icrovett
Nein Mein Problem ist, dass der Keystore funktioniert, wenn wir die Systemeigenschaften so einstellen, dass dieser Keystore verwendet wird. Aber wenn wir diesen Keystore in den Standard von jvm laden, dh cacerts, wird es nicht funktionieren. Es sagt schlechtes Zertifikat ..
Mrinal Bhattacharjee

Antworten:

109

Wenn Sie Tomcat 6 und früher verwenden, stellen Sie sicher, dass das Keystore-Kennwort und das Schlüsselkennwort identisch sind. Wenn Sie Tomcat 7 und höher verwenden, stellen Sie sicher, dass sie identisch sind oder dass das Schlüsselkennwort in der server.xmlDatei angegeben ist.

Captain Man
quelle
10
Das ist wahr. Referenz tomcat.apache.org/tomcat-6.0-doc/…
Atharva
2
Relevantes Zitat: Schließlich werden Sie zur Eingabe des Schlüsselkennworts aufgefordert , bei dem es sich um das Kennwort speziell für dieses Zertifikat handelt (im Gegensatz zu anderen Zertifikaten, die in derselben Keystore-Datei gespeichert sind). Sie MÜSSEN hier dasselbe Passwort verwenden, das für das Keystore-Passwort selbst verwendet wurde. Dies ist eine Einschränkung der Tomcat-Implementierung. (Derzeit werden Sie an der keytoolEingabeaufforderung darüber informiert, dass das Drücken der ENTER-Taste dies automatisch für Sie erledigt.)
Captain Man
Ich hatte dieses Problem mit JMeter (https), da der Java-Keystore und die Schlüsselkennwörter unterschiedlich waren. Ref stackoverflow.com/questions/2889238/… . um das Schlüsselkennwort zu ändern, um das Problem zu beheben. Tolle Hilfe! Vielen Dank.
Rishi
@CaptainMan, das gilt nur für Tomcat6, von Tomcat7 nicht .
Andrea Ligios
2
@AndreaLigios guter Punkt, relevantes Zitat: Schließlich werden Sie aufgefordert, das Schlüsselkennwort einzugeben , das das Kennwort speziell für dieses Zertifikat ist (im Gegensatz zu allen anderen Zertifikaten, die in derselben Keystore-Datei gespeichert sind). Die keytoolEingabeaufforderung zeigt an, dass beim Drücken der ENTER-Taste automatisch dasselbe Kennwort für die Taste wie für den Keystore verwendet wird. Es steht Ihnen frei, dasselbe Passwort zu verwenden oder ein benutzerdefiniertes Passwort auszuwählen. Wenn Sie ein anderes Kennwort als das Keystore-Kennwort auswählen, müssen Sie auch das benutzerdefinierte Kennwort in der server.xmlKonfigurationsdatei angeben .
Captain Man
72

Das in Ihrer App / Konfiguration definierte Kennwort für den privaten Schlüssel ist falsch. Überprüfen Sie zunächst das Kennwort für den privaten Schlüssel, indem Sie wie folgt zu einem anderen wechseln:

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

Im obigen Beispiel wird das Kennwort von Kennwort in Änderung geändert. Dieser Befehl ist erfolgreich, wenn das Kennwort für den privaten Schlüssel das Kennwort war.

Umesh Rajbhandari
quelle
2
Ich habe diese Antwort zwar nicht in Bezug auf die Frage verwendet. Dies war hilfreich für die Überprüfung einer Keystore-Datei, eines Speicherkennworts, eines Alias ​​/ Schlüssels und eines Schlüsselkennworts.
Russ
1
Bitte denken Sie daran, dass Sie nach Ausführung dieses Befehls das Keystore-Passwort ändern. Sie müssten das Passwort auf das ursprüngliche zurücksetzen.
GersonZaragocin
Eigentlich reicht es aus, nur anzugeben -keypasswd -keystore storefile -alias somealiasund alles andere in eine Eingabeaufforderung einzugeben.
Andrey Regentov
Beim Ausführen dieses Codes wird folgende Fehlermeldung angezeigt: "keytool error: java.security.UnrecoverableKeyException: Cannot recover key"Gibt es eine Möglichkeit, das Kennwort meines Alias-Schlüssels zu überprüfen oder zu ändern, ohne das alte zu kennen?
Kavin Raju S
10

Um die Cannot recover keyAusnahme nicht zu haben , musste ich die JCE-Richtliniendateien (Java Cryptography Extension) mit unbegrenzter Stärke auf die Installation von Java anwenden, auf der meine Anwendung ausgeführt wurde. Version 8 dieser Dateien finden Sie hier oder die neueste Version sollte auf dieser Seite aufgeführt sein . Der Download enthält eine Datei, in der erläutert wird, wie die Richtliniendateien angewendet werden.


Seit JDK 8u151 müssen keine Richtliniendateien hinzugefügt werden. Stattdessen werden die JCE-Zuständigkeitsrichtliniendateien von einer aufgerufenen Sicherheitseigenschaft gesteuert crypto.policy. Wenn Sie dies so einstellen, dass unlimiteddas JDK unbegrenzte Kryptografie verwenden kann. Wie in den oben genannten Versionshinweisen angegeben, kann dies über Security.setProperty()oder über die java.securityDatei festgelegt werden. Die java.securityDatei kann auch durch Hinzufügen -Djava.security.properties=my_security.propertieszum Befehl zum Starten des Programms angehängt werden, wie hier beschrieben .


Seit JDK 8u161 ist die unbegrenzte Kryptografie standardmäßig aktiviert.

Weißer Ritter
quelle
3
Ich sehe diesen Fehler, obwohl die JARs der Richtliniendatei installiert sind.
Adam
@Adam Meine Lösung ist für einen bestimmten Fall, der sich möglicherweise von dem unterscheidet, den Sie gerade erleben. Ich habe jedoch ein Update hinzugefügt, um die Änderung in JDK 8u151 widerzuspiegeln.
WhiteKnight
5

Ich hatte den gleichen Fehler, als wir einen Schlüssel in einen Keystore importierten, der mit einer 64-Bit-OpenSSL-Version erstellt wurde. Als wir das gleiche Verfahren befolgten, um den Schlüssel in einen Keystore zu importieren, der mit einer 32-Bit-OpenSSL-Version erstellt wurde, ging alles in Ordnung.

Heimi
quelle
3
Die Hauptursache für den obigen Fehler war java.security.UnrecoverableKeyException: Schlüssel kann nicht wiederhergestellt werden. Der Grund dafür kann ein falsches Passwort sein, wie oben erwähnt, aber auch ein Keystore-Build mit einer 64-Bit-OpenSSL-Implementierung. Daher betrachte ich meine Antwort als eine weitere mögliche Lösung. Es hat mir in der gleichen Fehlersituation geholfen, also habe ich hier die Lösung bereitgestellt.
Heimi
openssl erstellt keine Java-Keystore-Dateien. Könnten Sie das klarstellen?
Aled
Danke für deine Antwort. Ich habe das gleiche Problem beim Aufrufen von https-Webservices aus OpenESB 3.05. Ich folge Ihren Anweisungen und generiere die JKS-Datei erneut mit einer 32-Bit-Implementierung von OpenSS. Sie funktioniert einwandfrei
Marti Pàmies Solà,
2

Überprüfen Sie, ob das von Ihnen verwendete Kennwort korrekt ist, indem Sie den folgenden Befehl ausführen

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

Wenn der folgende Fehler auftritt, ist Ihr Passwort falsch

keytool error: java.security.UnrecoverableKeyException: Cannot recover key
Robin Mathur
quelle