Connexion à Secure Server en Java avec Apache Commons HttpClient 3.1 en lançant ValidatorException
-
06-07-2019 - |
Question
J'essaie de me connecter à un serveur sécurisé à l'aide de Apache Commons HttpClient 3.1
.
Le problème est que chaque fois que l'application se connecte, elle envoie un
sun.security.validator.ValidatorException.
Voici le stacktrace :
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: validation du chemin d'accès PKIX a échoué: java.security.cert.CertPathValidatorException: sujet / émetteur échec de la vérification du chaînage des noms javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: validation du chemin d'accès PKIX a échoué: java.security.cert.CertPathValidatorException: sujet / émetteur échec de la vérification du chaînage des noms à l'adresse com.sun.net.ssl.internal.ssl.Alerts.getSSLException (Alerts.java:174) à l'adresse com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal (SSLSocketImpl.java:1611) à l'adresse com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Handshaker.java:187) à l'adresse com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Handshaker.java:181) à l'adresse com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:1035) à l'adresse com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage (ClientHandshaker.java:124) à l'adresse com.sun.net.ssl.internal.ssl.Handshaker.processLoop (Handshaker.java:516) à l'adresse com.sun.net.ssl.internal.ssl.Handshaker.process_record (Handshaker.java:454) à l'adresse com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord (SSLSocketImpl.java:884) à l'adresse com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1112) à l'adresse com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord (SSLSocketImpl.java:623) à l'adresse com.sun.net.ssl.internal.ssl.AppOutputStream.write (AppOutputStream.java:59) sur java.io.BufferedOutputStream.flushBuffer (BufferedOutputStream.java:65) sur java.io.BufferedOutputStream.flush (BufferedOutputStream.java:123) à org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody (EntityEnclosingMethod.java:506) à org.apache.commons.httpclient.HttpMethodBase.writeRequest (HttpMethodBase.java:2114) à org.apache.commons.httpclient.HttpMethodBase.execute (HttpMethodBase.java:1096) à org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry (HttpMethodDirector.java:398) à org.apache.commons.httpclient.HttpMethodDirector.executeMethod (HttpMethodDirector.java:171) à org.apache.commons.httpclient.HttpClient.executeMethod (HttpClient.java:397) à org.apache.commons.httpclient.HttpClient.executeMethod (HttpClient.java:323) à balanceschecker.connector.Connector.conn (Connector.java:27) à balanceschecker.connector.Connector.RawPost (Connector.java:99) à balanceschecker.connector.Connector.Post (Connector.java:111) à balanceschecker.login.Login.Login (Login.java:87) at balanceschecker.Main.main (Main.java:21) Causé par: sun.security.validator.ValidatorException: validation du chemin d'accès PKIX a échoué: java.security.cert.CertPathValidatorException: sujet / émetteur échec de la vérification du chaînage des noms à sun.security.validator.PKIXValidator.doValidate (PKIXValidator.java:251) à sun.security.validator.PKIXValidator.doValidate (PKIXValidator.java:234) à sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:158) à sun.security.validator.Validator.validate (Validator.java:218) à l'adresse com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate (X509TrustManagerImpl.java:126) à l'adresse com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:209) à l'adresse com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:249) à l'adresse com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:1014) ... 21 de plus Causée par: java.security.cert.CertPathValidatorException: nom du sujet / nom de l'émetteur chaînage échoué à sun.security.provider.certpath.PKIXMasterCertPathValidator.validate (PKIXMasterCertPathValidator.java:139) à sun.security.provider.certpath.PKIXCertPathValidator.doValidate (PKIXCertPathValidator.java:326) à sun.security.provider.certpath.PKIXCertPathValidator.engineValidate (PKIXCertPathValidator.java:178) sur java.security.cert.CertPathValidator.validate (CertPathValidator.java:250) à sun.security.validator.PKIXValidator.doValidate (PKIXValidator.java:246) ... 28 autres
Voici le code que j'utilise (édité et un peu compacté)
installAllTrustManager(); PostMethod post = new PostMethod(server_path); NameValuePair[] data = new NameValuePair { new NameValuePair("Username", username), new NameValuePair("Password", password) }; post.setRequestBody(data); post.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); try { HttpClient hc = new HttpClient(); int result2 = hc.executeMethod(post); if (result2 != HttpStatus.SC_OK) { throw new IOException("HTTP Status Not OK: " + result2); } return post.getResponseBodyAsStream(); } finally { post.releaseConnection(); }
J'ai jeté un œil aux certificats du site et ils sont encore valables plus d'un an. J'ai ensuite essayé de contourner la vérification du certificat en utilisant le code présenté dans la section " Comment ignorer la vérification de l'hôte approuvé et du certificat dans Java ", mais l'exception est toujours levée.
Qu'est-ce que je fais mal?
Comment puis-je me connecter avec succès au serveur?
La solution
Cette erreur signifie qu'il ne peut pas valider la chaîne de certificats. Les causes possibles sont,
- L'autorité de certification racine n'est pas approuvée par votre JRE.
- Le certificat est signé par un certificat intermédiaire, mais le serveur ne l'envoie pas avec le certificat.
Voici comment obtenir une liste de certificats racine,
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -v
Je ne connais aucun moyen en Java de vérifier si un certificat intermédiaire est envoyé. J'utilise OpenSL pour cela,
openssl s_client -host example.com -port 443
Vous montrera tout le certificat envoyé par le serveur. Faites attention à la "Chaîne de certificats".