2009-05-06 9 views
7

Sto provando a leggere da una pagina Web protetta (ad esempio SSL), in codice Java. Sto cercando di utilizzare sia URLConnection (java.net) che Apache HTTPClient. In entrambi i casi, quando faccio la richiesta, ottengo questa eccezione:Impossibile autenticare il sito SSL in java: "pathLenConstraint violato - questo certificato deve essere l'ultimo certificato nel percorso di certificazione"

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: convalida del percorso PKIX non riuscita: java.security. cert.CertPathValidatorException: vincoli di base di controllo non sono riusciti: pathLenConstraint violata - questo cert deve essere l'ultima cert nel percorso di certificazione a com.sun.net.ssl.internal.ssl.Alerts.getSSLException (Alerts.java:150 a com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal (SSLSock etImpl.java:1518) a com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Handshaker.java:174) a com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Handshaker.java:168) a com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:848) a com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage (ClientHandshaker.java:106) a com.sun.net.ssl.internal.ssl.Handshaker.processLoop (Handshaker.java:495) a com.sun.net.ssl.internal.ssl.Handshaker.process_record (Handshaker.java:433) a com.sun.net.ssl.internal.ssl.SSLSocketIm pl.readRecord (SSLSocketImpl.java:818) a com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1030) a com.sun.net.ssl.internal.ssl. SSLSocketImpl.startHandshake (SSLSocketImpl.java:1057) a com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:1041) a sun.net.www.protocol.https.HttpsClient. afterConnect (HttpsClient.java:402) a sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect (AbstractDelegateHttpsURLConnection.java:166) a sun.net.www.protocol.http.HttpURLConnection.getInputStream (HttpURLConnection. java: 934) a sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream (HttpsURLConnectionImpl.java:234) a com.sap.river.coghead.rest.Main.testJavaHTTPConnection (Main.java:45) a com .sap.river.coghead.rest.Main.main (Main.java:32) causato da: sun.security.validator.ValidatorException: PKIX convalida del percorso non è riuscita: java.security.cert.CertPathValidatorException: vincoli di base check failed: pathLenConstraint violato - questo certificato deve essere l'ultimo certificato nel percorso di certificazione a sun.security.validator.PKIXValidator.doValidate (PKIXValida tor.java:187) a sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:139) a sun.security.validator.Validator.validate (Validator.java:203) a com.sun .net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:172) a com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted (SSLContextImpl.java: 320) a com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:841) ... 13 maggiori causati da: java.security.cert.CertPathValidatorException: vincoli di base un check fallito: pathLenConstraint violata - questo cert deve essere l'ultima cert nel percorso di certificazione a sun.security.provider.certpath.PKIXMasterCertPathValidator.validate (PKIXMasterCertPathValidator.java:139) a sun.security.provider.certpath .PKIXCertPathValidator.doValidate (PKIXCertPathValidator.java:316) a sun.security.provider.certpath.PKIXCertPathValidator.engineValidate (PKIXCert PathValidator.java:178) a java.security.cert.CertPathValidator.validate (CertPathValidator.java:206) a sun.security.validator.PKIXValidator.doValidate (PKIXValidator.java:182) ... 18 more

Si noti che sono riuscito a stabilire una connessione non-ssl, per un host diverso però. Sono anche in grado di visualizzare la pagina utilizzando il browser - i certificati sono convalidati correttamente lì.

Ti ho bisogno di cambiare in qualche modo l'ordine dei certificati in cui sono recuperati dal server? C'è qualche configurazione che mi manca?

Grazie in anticipo,

Lior

risposta

6

ho scavato nel ulteriormente e la risposta sta nel fatto che mi serviva per importare i certificati necessari nell'archivio chiavi utilizzata dalla JVM per l'autenticazione SSL. L'archivio delle chiavi è il file 'cacerts' nella cartella jre/lib/security in JRE che viene utilizzato per eseguire il programma.

ho esportato manualmente i certificati del sito - tutti loro.
Poi ho importato nel mio chiavi predefinito utilizzando l'utility 'keytool' fornito da Sun. Si noti che è necessario importarli nell'ordine corretto.
Ho poi messo il nuovo keystore al posto del JRE di uno - e ha funzionato.

Suppongo che sarebbe stato meglio importare i certificati direttamente nel keystore di JRE, ma lo strumento mi ha chiesto una password che non conoscevo.

Credo che ci sia anche un modo per programmarlo più facilmente, ma non l'abbiamo ancora trovato. Sarò felice di ottenere alcuni indicatori (classe TrustManager in JSSE?).

Infine, un po 'di credito. Questo post qui: http://javaishdiscoveries.blogspot.com/2009/02/battle-with-cacerts-and-https.html ha contribuito a indicarmi la giusta direzione.

+0

Non so se questo aiuta, ma Java consente di modificare lo SLLSocketFactory di default. – Powerlord

+0

sì, immagino di dover fare qualcosa in quell'area. Ho solo bisogno di investigare ulteriormente. - - Lior – Lior

+2

FYI, la password per il keystore di certificati Java predefinito $ JAVA_HOME/lib/security/cacerts è 'changeit' –

0

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: convalida del percorso PKIX non riuscita: java.security.cert.CertPathValidatorException: vincoli di base controllare fallito: pathLenConstraint violata - questo cert deve essere l'ultimo cert nel percorso di certificazione a

pathLenConstraint

See (Nota sui catene di certificati) in

http://groups.google.com/group/google-checkout-developers-forum/web/google-checkout-and-ssl-certificates?version=49

google dice che potrebbe essere un problema con l'ordine della catena di certificati, ho appena scoperto che il mio certificato non è in ordine, non è stato ancora risolto, lavorando su di esso. Lo aggiornerò più tardi.


vecchio post:

hanno quasi lo stesso problema.

L'aggiunta di certificato manualmente al keystore aiuta, ma preferirei farlo in modo più automatico, con il mio cliente.

Quindi la mia soluzione:

userò keystore proprio per questo un app, e un host 1. keystore non esiste - creare con alcune password generata 2. Salva password nel file di configurazione 3. Chiedere utente (o non) se vuole accettare questo certificato 4. se è così - salvarlo in keystore, e usarlo quando necessario

Questa è una buona soluzione? Qualche commento?

Problemi correlati