Causé par: java.security.UnrecoverableKeyException: impossible de récupérer la clé

84

Je suis fourni avec un keystore jks nommé ABCC_client.store. Lorsque j'importe ce keystore dans cacerts et que j'essaye de le connecter, il indique No such Algorithm error. PFA le 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

Mais si j'utilise ce keystore indépendamment c'est à dire sans l'ajouter aux cacerts ça marche.

Certains googlages m'ont conduit à http://joewlarson.com/blog/2009/03/25/java-ssl-use-the-same-password-for-keystore-and-key/ qui dit que le mot de passe pourrait être différent pour la clé et le keystore.

Mrinal Bhattacharjee
la source
Un peu de code pour voir ce qui s'appelle si possible?
Bruno
J'essayais d'appeler une méthode de service Web à partir du code..AxisFault faultCode: { schemas.xmlsoap.org/soap/envelope } Server.userException faultSubcode: faultString: java.net.SocketException: java.security.NoSuchAlgorithmException: Erreur lors de la construction implémentation (algorithme: par défaut, fournisseur: SunJSSE, classe: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Mrinal Bhattacharjee
2
Peut être dupliqué ici est une question similaire avec une réponse.
icrovett
Non Mon problème est que le keystore fonctionne si nous définissons les propriétés du système pour utiliser ce keystore. Mais si nous chargeons ce keystore dans le fichier par défaut de jvm, c'est-à-dire cacerts, il ne fonctionne pas. Il dit mauvais certificat ..
Mrinal Bhattacharjee

Réponses:

109

Si vous utilisez Tomcat 6 et versions antérieures, assurez-vous que le mot de passe du fichier de clés et le mot de passe de la clé sont identiques. Si vous utilisez Tomcat 7 et versions ultérieures, assurez-vous qu'ils sont identiques ou que le mot de passe clé est spécifié dans le server.xmlfichier.

Captain Man
la source
10
C'est vrai. Référence tomcat.apache.org/tomcat-6.0-doc/…
Atharva
2
Citation pertinente: Enfin, vous serez invité à entrer le mot de passe clé , qui est le mot de passe spécifiquement pour ce certificat (par opposition à tout autre certificat stocké dans le même fichier de clés). Vous DEVEZ utiliser ici le même mot de passe que celui utilisé pour le mot de passe du keystore lui-même. Il s'agit d'une restriction de l'implémentation Tomcat. (Actuellement, l' keytoolinvite vous indiquera que le fait d'appuyer sur la touche ENTRÉE le fait automatiquement pour vous.)
Captain Man
J'ai eu ce problème avec JMeter (https) car le keystore Java et les mots de passe clés étaient différents. Réf stackoverflow.com/questions/2889238/… . pour modifier le mot de passe clé pour résoudre le problème. Grande aide! Merci.
Rishi
@CaptainMan ce n'est vrai que dans Tomcat6, à partir de Tomcat7 ce n'est pas le cas .
Andrea Ligios
2
@AndreaLigios bon point, citation pertinente: Enfin, vous serez invité à entrer le mot de passe clé , qui est le mot de passe spécifiquement pour ce certificat (par opposition à tout autre certificat stocké dans le même fichier de clés). L' keytoolinvite vous indiquera que le fait d'appuyer sur la touche ENTRÉE utilise automatiquement le même mot de passe pour la clé que le fichier de clés. Vous êtes libre d'utiliser le même mot de passe ou d'en sélectionner un personnalisé. Si vous sélectionnez un mot de passe différent du mot de passe du server.xmlfichier de clés, vous devrez également spécifier le mot de passe personnalisé dans le fichier de configuration.
Captain Man
73

Le mot de passe de la clé privée défini dans votre application / configuration est incorrect. Essayez d'abord de vérifier le mot de passe de la clé privée en remplaçant par un autre comme suit:

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

L'exemple ci-dessus change le mot de passe de password à changeit. Cette commande réussira si le mot de passe de la clé privée était mot de passe.

Umesh Rajbhandari
la source
2
Bien que je n'ai pas utilisé cette réponse en relation avec la question. Cela a été utile pour valider un fichier de stockage de clés, un mot de passe de stockage, un alias / clé et un mot de passe clé.
Russ
1
N'oubliez pas qu'après avoir exécuté cette commande, vous modifierez le mot de passe du fichier de clés. Vous devrez redéfinir le mot de passe sur celui d'origine.
gersonZaragocin
en fait, il suffit de spécifier juste -keypasswd -keystore storefile -alias somealiaset de saisir tout le reste dans une invite.
Andrey Regentov
En exécutant ce code, j'obtiens l'erreur suivante - "keytool error: java.security.UnrecoverableKeyException: Cannot recover key"Existe - t-il un moyen de vérifier quel est mon mot de passe de clé d'alias ou de le modifier sans connaître l'ancien?
Kavin Raju S
10

Afin de ne pas avoir d' Cannot recover keyexception, j'ai dû appliquer les fichiers de stratégie de juridiction de force illimitée Java Cryptography Extension (JCE) à l'installation de Java qui exécutait mon application. La version 8 de ces fichiers peut être trouvée ici ou la dernière version devrait être répertoriée sur cette page . Le téléchargement comprend un fichier qui explique comment appliquer les fichiers de stratégie.


Depuis le JDK 8u151, il n'est pas nécessaire d'ajouter des fichiers de stratégie. Au lieu de cela, les fichiers de stratégie de juridiction JCE sont contrôlés par une propriété Security appelée crypto.policy. Définir cela sur unlimitedavec autorise l'utilisation d'une cryptographie illimitée par le JDK. Comme les notes de publication liées à l'état ci-dessus, il peut être défini par Security.setProperty()ou via le java.securityfichier. Le java.securityfichier peut également être ajouté en ajoutant -Djava.security.properties=my_security.propertiesà la commande pour démarrer le programme comme détaillé ici .


Depuis JDK 8u161, la cryptographie illimitée est activée par défaut.

Chevalier blanc
la source
3
Je vois cette erreur malgré l'installation des fichiers JAR de politique.
Adam
@Adam Ma solution est pour un cas spécifique, qui peut être différent de celui que vous rencontrez. Cependant, j'ai ajouté une mise à jour pour refléter le changement survenu dans le JDK 8u151.
WhiteKnight
5

J'ai eu la même erreur lorsque nous avons importé une clé dans un keystore qui a été construit à l'aide d'une version OpenSSL 64 bits. Lorsque nous avons suivi la même procédure pour importer la clé dans un keystore qui a été construit à l'aide d'une version OpenSSL 32 bits, tout s'est bien passé.

Heimi
la source
3
La cause première de l'erreur ci-dessus était java.security.UnrecoverableKeyException: impossible de récupérer la clé. La raison en est peut-être un faux mot de passe comme mentionné ci-dessus, mais aussi une construction de keystore avec une implémentation OpenSSL 64 bits. Je considère donc ma réponse comme une autre solution possible. Cela m'a aidé dans la même situation d'erreur, alors j'ai fourni la solution ici.
Heimi
openssl ne crée pas de fichiers de keystore Java. Pourriez-vous clarifier cela?
aled
Merci pour votre réponse. Je suis confronté au même problème lorsque j'appelle les services Web https sous OpenESB 3.05. Je suis vos instructions et génère à nouveau le fichier jks avec une implémentation 32 bits d'OpenSS et cela fonctionne très bien
Marti Pàmies Solà
2

Vérifiez si le mot de passe que vous utilisez est correct en exécutant la commande ci-dessous

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

Si vous obtenez une erreur ci-dessous, votre mot de passe est incorrect

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