2009-05-06 6 views
7

Próbuję odczytać z bezpieczny (tj SSL) strony internetowej, w kodzie Java. Próbuję użyć zarówno adresu URLConnection (java.net), jak i HTTPClient serwera Apache. W obu przypadkach, kiedy robię żądanie, otrzymuję ten wyjątek:Nie można uwierzytelnić witryny SSL w Java: „pathLenConstraint naruszone - ten cert musi być ostatnim cert w ścieżce certyfikacji”

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: sprawdzaniu ścieżki PKIX nie powiodło się: java.security. cert.CertPathValidatorException: podstawowe ograniczenia check failed: pathLenConstraint naruszone - ten cert musi być ostatnim cert w ścieżce certyfikacji na com.sun.net.ssl.internal.ssl.Alerts.getSSLException (Alerts.java:150) pod adresem com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal (SSLSock etImpl.java: 1518) pod adresem com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Handshaker.java:174) pod adresem com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Handshaker.java:168) pod adresem com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:848) pod adresem com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage (ClientHandshaker.java:106) pod adresem com.sun.net.ssl.internal.ssl.Handshaker.processLoop (Handshaker.java:495) pod adresem com.sun.net.ssl.internal.ssl.Handshaker.process_record (Handshaker.java:433) pod adresem com.sun.net.ssl.internal.ssl.SSLSocketIm pl.readRecord (SSLSocketImpl.java:818) pod adresem com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1030) pod adresem com.sun.net.ssl.internal.ssl. SSLSocketImpl.startHandshake (SSLSocketImpl.java:1057) w com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:1041) w sun.net.www.protocol.https.HttpsClient. afterConnect (HttpsClient.java:402) w sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect (AbstractDelegateHttpsURLConnection.java:166) w sun.net.www.protocol.http.HttpURLConnection.getInputStream (HttpURLConnection. java: 934) na sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream (HttpsURLConnectionImpl.java:234) w com.sap.river.coghead.rest.Main.testJavaHTTPConnection (Main.java:45) w com .sap.river.coghead.rest.Main.main (Main.java:32) spowodowane przez: sun.security.validator.ValidatorException: sprawdzaniu ścieżki PKIX Błędy: java.security.cert.CertPathValidatorException: podstawowymi ograniczeniami check failed: pathLenConstraint violated - ten certyfikat musi być ostatnim certyfikatem na ścieżce certyfikacji pod adresem sun.security.validator.PKIXValidator.doValidate (PKIXValida tor.java:187) w sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:139) w sun.security.validator.Validator.validate (Validator.java:203) w com.sun .net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:172) pod adresem com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted (SSLContextImpl.Java: 320) na com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:841) ... 13 więcej Spowodowany przez: java.security.cert.CertPathValidatorException: podstawowych ograniczeń check failed: pathLenConstraint naruszone - ten cert musi być ostatnim cert w ścieżce certyfikacji na sun.security.provider.certpath.PKIXMasterCertPathValidator.validate (PKIXMasterCertPathValidator.java:139) na sun.security.provider.certpath .PKIXCertPathValidator.doValidate (PKIXCertPathValidator.java:316) pod adresem sun.security.provider.certpath.PKIXCertPathValidator.engineValidate (PKIXCert PathValidator.java:178) na java.security.cert.CertPathValidator.validate (CertPathValidator.java:206) na sun.security.validator.PKIXValidator.doValidate (PKIXValidator.java:182) ... 18 więcej

Zauważ, że udało mi się nawiązać połączenie inne niż ssl z innym hostem. Mam również możliwość wyświetlenia tej strony za pomocą przeglądarki - certyfikaty są tam poprawnie sprawdzane.

Czy muszę w jakiś sposób zmienić kolejność certyfikatów, ponieważ są one pobierane z serwera? Czy brakuje jakiejś konfiguracji?

Dzięki z góry,

Lior

Odpowiedz

6

I wykopali dalej i odpowiedź leży w tym, że muszę importować niezbędne certyfikaty do kluczy używanych przez JVM do uwierzytelniania SSL. Magazyn kluczy to plik "cacerts" w folderze jre/lib/security w katalogu JRE używanym do uruchomienia programu.

Ręcznie wyeksportowałem certyfikaty witryny - wszystkie z nich.
Następnie zaimportowałem go do domyślnego magazynu kluczy, korzystając z narzędzia "keytool" dostarczonego przez firmę Sun. Pamiętaj, że musisz zaimportować je we właściwej kolejności.
Następnie umieściłem nowy magazyn kluczy zamiast JRE - i zadziałało.

Myślę, że lepiej byłoby zaimportować certyfikaty bezpośrednio do magazynu kluczy JRE, ale narzędzie poprosiło mnie o hasło, którego nie znałem.

Wierzę, że istnieje również sposób na łatwiejsze programowanie, po prostu jeszcze go nie znalazłem. Będę szczęśliwy, aby uzyskać wskazówki (klasa TrustManager w JSSE?).

Wreszcie trochę kredytu. Ten post tutaj: http://javaishdiscoveries.blogspot.com/2009/02/battle-with-cacerts-and-https.html pomógł mi wskazać właściwy kierunek.

+0

ja nie wiem, czy to pomoże, ale Java pozwala na zmianę domyślnej SLLSocketFactory. – Powerlord

+0

tak, wyobrażam sobie, że muszę coś z tym zrobić. Wystarczy zbadać to dalej. Dzięki, - Lior – Lior

+2

FYI, hasło do domyślnego pliku kluczy certyfikatów Java $ JAVA_HOME/lib/security/cacerts to "zmień" –

0

Wyjątek javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: weryfikacja ścieżki PKIX nie powiodła się: java.security.cert.CertPathValidatorException: podstawowe ograniczenia sprawdzić nie powiodło się: pathLenConstraint naruszone - ten cert musi być ostatnim cert w ścieżce certyfikacji w

pathLenConstraint

zobaczyć (nota o łańcuchach certyfikat) w

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

Google twierdzi, że może to być problem z zamówieniem łańcucha certyfikatów. Właśnie stwierdziłem, że mój certyfikat nie jest w porządku, a nie naprawiony, i pracuje nad nim. Zaktualizuję to później.


stary wpis:

prawie ten sam problem.

Ręczne dodawanie certyfikatu do magazynu kluczy pomaga, ale wolałbym zrobić to bardziej automatycznie z moim klientem.

Więc moje rozwiązanie:

będę używać kluczy tylko dla tej jednej aplikacji, a jeden gospodarz 1. kluczy nie istnieje - utworzyć z pewnym wygenerowane hasło 2. Zapisz hasło w pliku konfiguracyjnym 3. zapytać użytkownik (lub nie), czy chce zaakceptować ten certyfikat 4. Jeśli tak - zapisz go w magazynie kluczy i użyj go w razie potrzeby

Czy to jest dobre rozwiązanie? Wszelkie komentarze?

Powiązane problemy