Causado por: java.security.UnrecoverableKeyException: no se puede recuperar la clave

84

Se me proporciona un almacén de claves jks llamado ABCC_client.store. Cuando importo este almacén de claves a cacerts e intento conectarlo, dice No hay tal error de algoritmo. PFA el 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

Pero si uso este almacén de claves de forma independiente, es decir, sin agregarlo a cacerts, funciona.

Algunas búsquedas en Google me llevaron a http://joewlarson.com/blog/2009/03/25/java-ssl-use-the-same-password-for-keystore-and-key/ que dice que la contraseña podría ser diferente para la clave y el almacén de claves.

Mrinal Bhattacharjee
fuente
¿Un poco de código para ver cómo se llama si es posible?
Bruno
Estaba intentando llamar a un método de servicio web desde dentro del código ... AxFault failureCode: { schemas.xmlsoap.org/soap/envelope } Server.userException failureSubcode: failureString: java.net.SocketException: java.security.NoSuchAlgorithmException: Error al construir implementación (algoritmo: predeterminado, proveedor: SunJSSE, clase: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Mrinal Bhattacharjee
2
Puede ser duplicado aquí hay una pregunta similar con una respuesta.
icrovett
No Mi problema es que el almacén de claves funciona si configuramos las propiedades del sistema para usar ese almacén de claves. Pero si cargamos ese almacén de claves en el valor predeterminado de jvm, es decir, cacerts, no lo hace. Dice certificado incorrecto ...
Mrinal Bhattacharjee

Respuestas:

109

Si utiliza Tomcat 6 y versiones anteriores, asegúrese de que la contraseña del almacén de claves y la contraseña de la clave sean las mismas. Si usa Tomcat 7 y posterior, asegúrese de que sean iguales o que la contraseña de la clave esté especificada en el server.xmlarchivo.

Capitán Man
fuente
10
Esto es verdad. Referencia tomcat.apache.org/tomcat-6.0-doc/…
Atharva
2
Cita relevante: Finalmente, se le pedirá la contraseña de la clave , que es la contraseña específica para este Certificado (a diferencia de cualquier otro Certificado almacenado en el mismo archivo de almacén de claves). Usted DEBE usar la misma contraseña aquí que se utilizó para la propia contraseña del almacén. Esta es una restricción de la implementación de Tomcat. (Actualmente, el keytoolmensaje le dirá que presionar la tecla ENTER hace esto automáticamente).
Capitán Man
Tuve este problema con JMeter (https) porque el almacén de claves de Java y las contraseñas clave eran diferentes. Ref . Stackoverflow.com/questions/2889238/… . para cambiar la contraseña de la clave para resolver el problema. ¡Gran ayuda! Gracias.
Rishi
@CaptainMan eso solo es cierto en Tomcat6, de Tomcat7 no lo es .
Andrea Ligios
2
@AndreaLigios buen punto, cita relevante: Finalmente, se le pedirá la contraseña de la clave , que es la contraseña específicamente para este Certificado (a diferencia de cualquier otro Certificado almacenado en el mismo archivo de almacén de claves). El keytoolmensaje le dirá que presionar la tecla ENTER automáticamente usa la misma contraseña para la clave que el almacén de claves. Puede utilizar la misma contraseña o seleccionar una personalizada. Si selecciona una contraseña diferente a la contraseña del almacén de claves, también deberá especificar la contraseña personalizada en el server.xmlarchivo de configuración.
Captain Man
73

La contraseña de la clave privada definida en su aplicación / configuración es incorrecta. Primero intente verificar la contraseña de la clave privada cambiando a otra de la siguiente manera:

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

El ejemplo anterior cambia la contraseña de contraseña a changeit. Este comando tendrá éxito si la contraseña de la clave privada era contraseña.

Umesh Rajbhandari
fuente
2
Si bien no usé esta respuesta en relación con la pregunta. Fue útil para validar un archivo de almacén de claves, contraseña de almacén, alias / clave y contraseña de clave.
Russ
1
Recuerde que después de ejecutar este comando, cambiará la contraseña del almacén de claves. Tendría que volver a establecer la contraseña original.
gersonZaragocin
en realidad, es suficiente especificar solo -keypasswd -keystore storefile -alias somealiase ingresar todo lo demás en un mensaje.
Andrey Regentov
Al ejecutar este código, "keytool error: java.security.UnrecoverableKeyException: Cannot recover key"aparece el siguiente error: ¿Hay alguna forma de verificar cuál es la contraseña de mi clave de alias o de cambiarla sin conocer la anterior?
Kavin Raju S
10

Para no tener la Cannot recover keyexcepción, tuve que aplicar los archivos de política de jurisdicción de fuerza ilimitada de Java Cryptography Extension (JCE) a la instalación de Java que estaba ejecutando mi aplicación. La versión 8 de esos archivos se puede encontrar aquí o la última versión debe aparecer en esta página. . La descarga incluye un archivo que explica cómo aplicar los archivos de políticas.


Desde JDK 8u151 no es necesario agregar archivos de política. En su lugar, los archivos de políticas de jurisdicción de JCE están controlados por una propiedad de seguridad llamada crypto.policy. Configurar eso para unlimitedpermitir que el JDK utilice criptografía ilimitada. Como las notas de la versión vinculadas al estado anterior, se puede configurar mediante Security.setProperty()o mediante el java.securityarchivo. El java.securityarchivo también se puede agregar agregando -Djava.security.properties=my_security.propertiesal comando para iniciar el programa como se detalla aquí .


Dado que JDK 8u161, la criptografía ilimitada está habilitada de forma predeterminada.

Caballero blanco
fuente
3
Veo este error a pesar de tener instalados los archivos jar del archivo de política.
Adam
@Adam Mi solución es para un caso específico, que puede ser diferente al que estás viviendo. Sin embargo, agregué una actualización para reflejar el cambio que ocurrió en JDK 8u151.
WhiteKnight
5

Tuve el mismo error cuando importamos una clave en un almacén de claves que se construyó con una versión OpenSSL de 64 bits. Cuando seguimos el mismo procedimiento para importar la clave a un almacén de claves que se creó con una versión OpenSSL de 32 bits, todo salió bien.

Heimi
fuente
3
La causa raíz del error anterior fue java.security.UnrecoverableKeyException: no se puede recuperar la clave. El motivo puede ser una contraseña falsa como se mencionó anteriormente, pero también una compilación de almacén de claves con una implementación OpenSSL de 64 bits. Entonces considero mi respuesta como otra posible solución. Me ayudó en la misma situación de error, así que proporcioné la solución aquí.
Heimi
openssl no crea archivos de almacén de claves de Java. ¿Podrías aclarar esto?
aled
Gracias por tu respuesta. Me enfrento al mismo problema al invocar los servicios web https desde OpenESB 3.05. Sigo sus instrucciones y genero el archivo jks nuevamente con una implementación de 32 bits de OpenSS y funciona bien
Marti Pàmies Solà
2

Verifique si la contraseña que está utilizando es la correcta ejecutando el siguiente comando

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

Si obtiene el siguiente error, su contraseña es incorrecta

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