Вызвано: java.security.UnrecoverableKeyException: невозможно восстановить ключ

84

Мне предоставлено хранилище ключей jks с именем ABCC_client.store. Когда я импортирую это хранилище ключей в cacerts и пытаюсь подключиться, появляется сообщение Нет такой ошибки алгоритма. PFA трассировка стека

    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

Но если я использую это хранилище ключей независимо, то есть без добавления его в cacerts, оно работает.

Некоторый поиск в Google привел меня к http://joewlarson.com/blog/2009/03/25/java-ssl-use-the-same-password-for-keystore-and-key/, в котором говорится, что пароль может быть другим для ключ и хранилище ключей.

Мринал Бхаттачарджи
источник
Немного кода, чтобы узнать, что называется, если возможно?
Бруно
Я пытался вызвать метод веб-службы из кода..AxisFault faultCode: { schemas.xmlsoap.org/soap/envelope } Server.userException faultSubcode: faultString: java.net.SocketException: java.security.NoSuchAlgorithmException: Ошибка построения реализация (алгоритм: по умолчанию, поставщик: SunJSSE, класс: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Мринал Бхаттачарджи
2
Может быть продублирован вот аналогичный вопрос с ответом.
icrovett
Нет Моя проблема в том, что хранилище ключей работает, если мы настроили свойства системы для использования этого хранилища ключей. Но если мы загрузим это хранилище ключей в jvm по умолчанию, т.е. cacerts, оно выполнит wrk. Там написано плохой сертификат ..
Мринал Бхаттачарджи

Ответы:

109

При использовании Tomcat 6 и более ранних версий убедитесь, что пароль хранилища ключей и пароль ключа совпадают. При использовании Tomcat 7 и более поздних версий убедитесь, что они совпадают или что ключевой пароль указан в server.xmlфайле.

Капитан человек
источник
10
Это правда. Ссылка tomcat.apache.org/tomcat-6.0-doc/…
Атхарва
2
Соответствующая цитата: наконец, вам будет предложено ввести пароль ключа , который является паролем специально для этого сертификата (в отличие от любых других сертификатов, хранящихся в том же файле хранилища ключей). Вы ДОЛЖНЫ использовать здесь тот же пароль, который использовался для самого пароля хранилища ключей. Это ограничение реализации Tomcat. (В настоящее время в keytoolподсказке будет сказано, что нажатие клавиши ENTER сделает это за вас автоматически.)
Captain Man
У меня была эта проблема с JMeter (https), потому что хранилище ключей Java и пароли ключей были разными. Ссылка stackoverflow.com/questions/2889238/… . для изменения ключевого пароля для решения проблемы. Большая помощь! Благодарю.
Риши
@CaptainMan это правда только в Tomcat6, из Tomcat7 - нет .
Андреа Лиджиос 02
2
@AndreaLigios хороший момент, соответствующая цитата: наконец, вам будет предложено ввести пароль ключа , который является паролем специально для этого сертификата (в отличие от любых других сертификатов, хранящихся в том же файле хранилища ключей). keytoolПодсказка покажет вам , что при нажатии клавиши ВВОД автоматически использует один и тот же пароль для ключа в хранилище ключей. Вы можете использовать тот же пароль или выбрать собственный. Если вы выберете пароль, отличный от пароля хранилища ключей, вам также потребуется указать собственный пароль в server.xmlфайле конфигурации.
Captain Man
73

Пароль закрытого ключа, указанный в вашем приложении / конфигурации, неверен. Сначала попробуйте проверить пароль закрытого ключа, изменив его на другой следующим образом:

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

В приведенном выше примере пароль меняется с пароля на changeit. Эта команда будет успешной, если паролем секретного ключа был пароль.

Умеш Раджбхандари
источник
2
Пока я не использовал этот ответ в отношении вопроса. Это было полезно для проверки файла хранилища ключей, пароля хранилища, псевдонима / ключа и ключевого пароля.
Russ
1
Помните, что после выполнения этой команды вы измените пароль хранилища ключей. Вам нужно будет восстановить исходный пароль.
gersonZaragocin
на самом деле достаточно указать просто -keypasswd -keystore storefile -alias somealiasи ввести все остальное в командной строке.
Андрей Регентов
При запуске этого кода я получаю следующую ошибку: "keytool error: java.security.UnrecoverableKeyException: Cannot recover key"есть ли способ проверить, какой у меня пароль ключа псевдонима, или изменить его, не зная старого?
Kavin Raju S
10

Чтобы не было Cannot recover keyисключения, мне пришлось применить файлы политики юрисдикции неограниченной надежности Java Cryptography Extension (JCE) к установке Java, на которой выполнялось мое приложение. Версию 8 этих файлов можно найти здесь или последнюю версию необходимо указать на этой странице . Загружаемый файл включает файл, объясняющий, как применять файлы политики.


Начиная с JDK 8u151 нет необходимости добавлять файлы политик. Вместо этого файлы политик юрисдикции JCE контролируются свойством Security с именем crypto.policy. Установка этого параметра unlimitedпозволяет JDK использовать неограниченное количество криптографии. Поскольку примечания к выпуску связаны с указанным выше состоянием, его можно установить с Security.setProperty()помощью java.securityфайла. java.securityФайл также может быть добавлен к путем добавления -Djava.security.properties=my_security.propertiesк команде , чтобы запустить программу , как описано здесь .


Поскольку JDK 8u161 неограниченное шифрование включено по умолчанию.

Белый рыцарь
источник
3
Я вижу эту ошибку, несмотря на то, что установлены jar-файлы политики.
Adam
@Adam Мое решение предназначено для конкретного случая, который может отличаться от того, с которым вы столкнулись. Однако я добавил обновление, чтобы отразить изменение, произошедшее в JDK 8u151.
WhiteKnight
5

У меня была такая же ошибка, когда мы импортировали ключ в хранилище ключей, созданное с использованием 64-битной версии OpenSSL. Когда мы выполнили ту же процедуру для импорта ключа в хранилище ключей, которое было построено с использованием 32-разрядной версии OpenSSL, все прошло нормально.

Хейми
источник
3
Основной причиной указанной выше ошибки было исключение java.security.UnrecoverableKeyException: невозможно восстановить ключ. Причиной этого может быть ложный пароль, как упоминалось выше, а также сборка хранилища ключей с 64-битной реализацией OpenSSL. Поэтому я рассматриваю свой Ответ как еще одно возможное решение. Это помогло мне в той же ситуации с ошибкой, поэтому я предоставил решение здесь.
Хейми
openssl не создает файлы хранилища ключей Java. Не могли бы вы прояснить это?
Aled
Спасибо за ответ. Я сталкиваюсь с той же проблемой при вызове веб-служб https из OpenESB 3.05. Я следую вашим инструкциям и снова создаю файл jks с 32-битной реализацией OpenSS, и он отлично работает
Марти Пэмис Сола
2

Проверьте, правильный ли пароль вы используете, выполнив команду ниже

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

Если вы получаете сообщение об ошибке ниже, значит, ваш пароль неверен

keytool error: java.security.UnrecoverableKeyException: Cannot recover key
Робин Матур
источник