Przyczyna: java.security.UnrecoverableKeyException: Nie można odzyskać klucza

84

Otrzymuję magazyn kluczy JKS o nazwie ABCC_client.store. Kiedy importuję ten magazyn kluczy do cacerts i próbuję podłączyć, pojawia się komunikat Brak takiego błędu algorytmu. 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

Ale jeśli używam tego magazynu kluczy niezależnie, tj. Bez dodawania go do cacerts, to działa.

Niektóre googlowania doprowadziły mnie do http://joewlarson.com/blog/2009/03/25/java-ssl-use-the-same-password-for-keystore-and-key/, co oznacza, że ​​hasło może być inne dla klucz i magazyn kluczy.

Mrinal Bhattacharjee
źródło
Trochę kodu, aby zobaczyć, jak się nazywa, jeśli to możliwe?
Bruno,
Próbowałem wywołać metodę usługi sieciowej z poziomu kodu..AxisFault faultCode: { schemas.xmlsoap.org/soap/envelope } Server.userException faultSubcode: faultString: java.net.SocketException: java.security.NoSuchAlgorithmException: Błąd podczas tworzenia implementacja (algorytm: domyślny, dostawca: SunJSSE, klasa: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Mrinal Bhattacharjee
2
Można tutaj powtórzyć, jest podobne pytanie z odpowiedzią.
icrovett
Nie Moim problemem jest to, że magazyn kluczy działa, jeśli ustawimy właściwości systemu, aby używać tego magazynu kluczy. Ale jeśli załadujemy ten magazyn kluczy do domyślnego pliku jvm, czyli cacerts, zrobi to wrk. Mówi o złym certyfikacie ...
Mrinal Bhattacharjee

Odpowiedzi:

109

Jeśli używasz Tomcat 6 i wcześniejszych, upewnij się, że hasło magazynu kluczy i hasło klucza są takie same. Jeśli używasz Tomcat 7 i nowszych, upewnij się, że są takie same lub że hasło klucza jest określone w server.xmlpliku.

Kapitanie Man
źródło
10
To prawda. Odniesienie tomcat.apache.org/tomcat-6.0-doc/…
Atharva
2
Odpowiedni cytat: Na koniec zostaniesz poproszony o podanie hasła klucza , które jest hasłem specyficznym dla tego certyfikatu (w przeciwieństwie do innych certyfikatów przechowywanych w tym samym pliku kluczy). W tym miejscu MUSISZ użyć tego samego hasła, które zostało użyte dla samego hasła do magazynu kluczy. To jest ograniczenie implementacji Tomcat. (Obecnie keytoolpodpowiedź poinformuje Cię, że naciśnięcie klawisza ENTER robi to automatycznie.)
Kapitan Man
Miałem ten problem w JMeter (https) coz Java keystore i hasła kluczy były różne. Zobacz stackoverflow.com/questions/2889238/… . zmienić hasło klucza, aby rozwiązać problem. Wielka pomoc! Dzięki.
Rishi
@CaptainMan to prawda tylko w Tomcat6, z Tomcat7 tak nie jest .
Andrea Ligios
2
@AndreaLigios Dobra uwaga, odpowiedni cytat: Na koniec zostaniesz poproszony o podanie hasła klucza , które jest hasłem specyficznym dla tego certyfikatu (w przeciwieństwie do innych certyfikatów przechowywanych w tym samym pliku kluczy). keytoolSzybka powie, że naciskając klawisz ENTER automatycznie używa tego samego hasła dla klucza jako kluczy. Możesz użyć tego samego hasła lub wybrać własne. Jeśli wybierzesz inne hasło niż hasło magazynu kluczy, będziesz musiał także określić hasło niestandardowe w server.xmlpliku konfiguracyjnym.
Kapitan Man
73

Hasło klucza prywatnego zdefiniowane w aplikacji / konfiguracji jest nieprawidłowe. Najpierw spróbuj zweryfikować hasło klucza prywatnego, zmieniając na inne w następujący sposób:

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

Powyższy przykład zmienia hasło z password na changeit. To polecenie powiedzie się, jeśli hasło klucza prywatnego to hasło.

Umesh Rajbhandari
źródło
2
Chociaż nie użyłem tej odpowiedzi w odniesieniu do pytania. Było to pomocne przy sprawdzaniu poprawności pliku kluczy, przechowywaniu hasła, aliasu / klucza i hasła klucza.
Russ,
1
Pamiętaj, że po wykonaniu tego polecenia zmienisz hasło magazynu kluczy. Trzeba by było ustawić hasło z powrotem na oryginalne.
gersonZaragocin
właściwie wystarczy tylko określić -keypasswd -keystore storefile -alias somealiasi wpisać wszystko inne w monicie.
Andrey Regentov
Podczas uruchamiania tego kodu "keytool error: java.security.UnrecoverableKeyException: Cannot recover key"pojawia się następujący błąd - Czy jest jakiś sposób, aby sprawdzić, jakie jest moje hasło klucza aliasu lub zmienić je bez znajomości starego?
Kavin Raju S
10

Aby nie mieć Cannot recover keywyjątku, musiałem zastosować rozszerzenie Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files do instalacji Javy, na której była uruchomiona moja aplikacja. Wersję 8 tych plików można znaleźć tutaj lub najnowszą wersję należy wyświetlić na tej stronie . Pobieranie zawiera plik wyjaśniający, jak zastosować pliki zasad.


Od JDK 8u151 nie ma potrzeby dodawania plików strategii. Zamiast tego pliki zasad jurysdykcji JCE są kontrolowane przez właściwość Security o nazwie crypto.policy. Ustawienie tej opcji na unlimitedzezwala na używanie nieograniczonej kryptografii przez JDK. Ponieważ uwagi do wydania powiązane z powyższym stanem, można je ustawić za Security.setProperty()pomocą java.securitypliku lub za jego pośrednictwem . java.securityPlik może być również dołączane do dodając -Djava.security.properties=my_security.propertiesdo polecenia, aby uruchomić program jak opisano tutaj .


Od JDK 8u161 nieograniczona kryptografia jest domyślnie włączona.

Biały rycerz
źródło
3
Widzę ten błąd pomimo zainstalowania pliku zasad jars.
Adam
@Adam Moje rozwiązanie dotyczy konkretnego przypadku, który może różnić się od tego, którego doświadczasz. Dodałem jednak aktualizację odzwierciedlającą zmianę, która nastąpiła w JDK 8u151.
WhiteKnight,
5

Miałem ten sam błąd, kiedy zaimportowaliśmy klucz do magazynu kluczy, który został zbudowany przy użyciu 64-bitowej wersji OpenSSL. Kiedy zastosowaliśmy tę samą procedurę, aby zaimportować klucz do magazynu kluczy, który został zbudowany przy użyciu 32-bitowej wersji OpenSSL, wszystko poszło dobrze.

Heimi
źródło
3
Główną przyczyną powyższego błędu był java.security.UnrecoverableKeyException: nie można odzyskać klucza. Przyczyną może być fałszywe hasło, jak wspomniano powyżej, ale także kompilacja magazynu kluczy z 64-bitową implementacją OpenSSL. Dlatego uważam swoją odpowiedź za kolejne możliwe rozwiązanie. Pomogło mi to w tej samej sytuacji błędu, więc podałem tutaj rozwiązanie.
Heimi
openssl nie tworzy plików kluczy Java. Czy mógłbyś to wyjaśnić?
aled
Dziękuję za odpowiedź. Napotykam ten sam problem podczas wywoływania usług internetowych https z OpenESB 3.05. Postępuję zgodnie z twoimi instrukcjami i ponownie generuję plik jks z 32-bitową implementacją OpenSS i działa dobrze
Marti Pàmies Solà
2

Sprawdź, czy hasło, którego używasz, jest poprawne, uruchamiając poniższe polecenie

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

Jeśli otrzymujesz poniższy błąd, Twoje hasło jest nieprawidłowe

keytool error: java.security.UnrecoverableKeyException: Cannot recover key
Robin Mathur
źródło