2012-06-22 7 views
11

J'ai un problème étrange - un fournisseur utilise TLS SSLv3 avec un certificat client et serveur auto-signé. Cela n'a pas posé de problème avec Java1.5 et Java1.6 - il suffit d'importer le certificat client et la clé privée dans un fichier de clés et le certificat public du serveur dans le fichier de clés certifiées. Tout fonctionne bien. Toutefois, avec Java7, le certificat du serveur ne peut pas être approuvé même si le même fichier de clés certifiées est utilisé. J'ai essayé Windows et Red Hat à la fois en utilisant Java7 (versions 1.7.03, 04 et 05, x86 et x64) sans succès.Java7 Refuser de faire confiance au certificat dans le magasin de confiance

J'ai recréé le keystore/truststore à partir de zéro et ils contiennent uniquement ces certificats. Les propriétés système appropriées ont été définies (javax.net.ssl.keyStore, javax.net.ssl.trustStore) et l'aspect clé est que le même code et la même configuration fonctionnent parfaitement dans JDK5/6. Je ne peux pas trouver de référence à une vérification supplémentaire, mais j'aurais pensé que le fait que le certificat se trouve dans le truststore devrait signifier qu'il est approuvé, même s'il est auto-signé.

Toute aide appréciée. annonces

trace d'exception:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:  sun.security.validator.ValidatorException: PKIX path validation failed:  java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors 
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors 
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868) 
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) 
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) 
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1338) 
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154) 
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) 
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) 
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998) 
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294) 
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685) 
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111) 
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) 
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291) 
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295) 
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141) 
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229) 
at com.alltria.ypsilon.testing.TestSSL.main(TestSSL.java:65) 
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors 
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:350) 
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:249) 
at sun.security.validator.Validator.validate(Validator.java:260) 
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) 
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) 
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) 
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320) 
... 13 more 
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors 
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:208) 
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:279) 
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:345) 
... 19 more 
Java Result: 1 

La partie où le débogage ssl échoue tente de valider le certificat du serveur:

*** 
%% Invalidated: [Session-1, SSL_RSA_WITH_RC4_128_SHA] 
main, SEND SSLv3 ALERT: fatal, description = certificate_unknown 
main, WRITE: SSLv3 Alert, length = 2 
[Raw write]: length = 7 
0000: 15 03 00 00 02 02 2E        ....... 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors 
main, called close() 
main, called closeInternal(true) 
+0

Salutations de Ypsilon, nous travaillons là-dessus :) –

+0

Peut-être est lié à http: // bogues .sun.com/bugdatabase/view_bug.do? bu g_id = 7018897 ?? – Pma

+0

Pouvez-vous ajouter '-Djavax.net.debug = all' à votre ligne de commande 'java' et publiez le journal résultant complet, en particulier où le magasin de confiance est chargé? –

Répondre

9

J'ai eu en fait une question quelque peu similaire, où une application Tomcat ferait confiance au ca cert dans le truststore lors de l'utilisation de Java 1.6 et le rejetterait avec java 1.7. Après l'ajout de keyUsage à mon certificat ca il fonctionne (après avoir lu un rapport de bug, JDK-7018897 : CertPath validation cannot handle self-signed cert with bad KeyUsage).

Ce que je l'ai fait (Ubuntu 12.04 64 bits):

  1. Modifier /etc/ssl/openssl.cnf et uncomment keyUsage ligne dans la section v3_ca.
  2. Créer nouveau ca cert de vieux avec keyUsage inclus en utilisant la commande:

    openssl x509 -in oldca.pem -clrext -signkey oldca.key -extfile /etc/ssl/openssl.cnf -extensions v3_ca -out newca.pem 
    
  3. Supprimer ancienne clé CA de truststore et insérez le nouveau.

+0

Voir [RFC 5280] (http://tools.ietf.org/html/rfc5280) et [RFC 6125] (http://tools.ietf.org/html/ rfc6125) pour les règles que Java utilise. – jww

+1

Comment cette solution fonctionne-t-elle dans un environnement Windows? Je n'ai pas le fichier openssl.cnf. En regardant le rapport de bug je ne suis pas sûr de ce que le correctif est. Suis-je censé récupérer le certificat en Java et le modifier lors de l'exécution? Ne semble pas être la bonne solution ... – IcedDante

+0

Pour être plus précis ... J'ai installé openSSL, j'ai téléchargé le certificat du serveur cible. Mais je ne suis pas sûr de savoir comment j'obtiens le fichier oldca.key. De plus, je pensais que les certificats étaient gérés avec une extension "crt". Y a-t-il une raison pour laquelle vous utilisez pem? – IcedDante

0

J'ai également rencontré cette situation en traitant avec JDK 1.7. Si la commande req est invoquée avec l'option -x509, il est préférable de décommenter keyUsage ligne v3_ca section et générer le CA à nouveau avec (voir http://wwwneu.secit.at/web/documentation/openssl/openssl_cnf.html)

openssl req -new -x509 -days 3650 -keyout ca.key -out ca.crt -config openssl.cnf -extensions v3_ca -batch 

Et si vous utilisez le certificat CA généré de signer un autre certificat assurez-vous que vous aussi décommenté l'élément basicConstraints = CA: true et la valeur à true

+2

L'URL que vous avez publiée ne fonctionne pas. Avez-vous une mise à jour? – IcedDante

+0

@IcedDante - Voir [Comment signer les demandes de signature de certificat OpenSSL auprès de votre autorité de certification?] (Https://stackoverflow.com/questions/21297139/how-do-you-sign-openssl-certificate-signing-requests-with -your-certification-aut) sur le dépassement de pile. – jww

Questions connexes