2012-07-31 10 views
17

Buduję prosty monitor aplikacji, aby sondować jeden z naszych adresów URL API i wysłać do nas e-mail, jeśli nie można uzyskać kodu statusu HTTP 200 z odpowiedzi (to oznaczałoby nasz interfejs API nie działa z jakiegoś powodu).Błąd "Peer Not Authenticated" SSL z HttpClient 4.1

używam HttpClient 4,1 (to ważne, ponieważ jego API różni znacznie od 3.x).

Nasz API jest bezpiecznym protokołem SSL, jednak wpisując:

http://example.com/our-api

w przeglądarce internetowej przekierowuje do

https://example.com/our-api

bez powodowania błędy.

Kiedy HttpClient próbuje uderzyć ten URL (http://example.com/our-api), to nie z javax.net.ssl.SSLPeerUnverifiedException wyjątek z komunikatem stwierdzając:

Peer nie uwierzytelnioną

widzę to dzieje się wiele innych osób o czym świadczy post this (który również zapewnia pewne sposoby obejścia tego problemu - rozwiązanie, które mam zamiar dzisiaj wprowadzić i faktycznie wprowadzić).

To, czego ten drugi post (i inne podobne do niego) nie wyjaśnia, dlaczego tak się dzieje! Zamiast pytać "jak to naprawić?" Pomyślałem Prosiłbym „dlaczego tak się dzieje?” Zanim pójdę barging naprzód z jednym z proponowanych rozwiązań, chciałbym wiedzieć, na czym polega problem, że jestem stara się naprawić ;-)

+1

mógłbyś zamieścić pełną ślad stosu? –

+0

Należy zauważyć, że ten komunikat musi wynikać z dziwnego programowania w HttpClient. Byłaby wcześniejsza "usterka uzgadniania" przez SSLException i to właśnie powinno być rzucone. Najwyraźniej wykonanie kontynuowało wywołanie SSLSession.getPeerCertificate(), które jest jedynym interfejsem API, który zgłasza wyjątek w tytule. – EJP

Odpowiedz

24

Jeśli certyfikat serwera jest samopodpisany, to działa zgodnie z założeniami i będziesz musiał zaimportować certyfikat serwera do magazynu kluczy.

Założenie, że certyfikat serwera jest podpisany przez dobrze znany urząd certyfikacji, dzieje się tak, ponieważ zestaw certyfikatów CA dostępny dla nowoczesnej przeglądarki jest znacznie większy niż ograniczony zestaw dostarczany z JDK/JRE.

Rozwiązanie EasySSL podane w jednym ze wspomnianych postów po prostu zakopuje błąd, a użytkownik nie będzie wiedział, czy serwer ma ważny certyfikat.

Musisz zaimportować właściwy główny urząd certyfikacji do magazynu kluczy, aby sprawdzić certyfikat. Jest powód, dla którego nie można obejść tego przy użyciu zapasowego kodu SSL, a to zapobiega pisaniu programów, które zachowują się tak, jakby były bezpieczne, ale nie są.

+0

W większości przypadków serwer SSL wysyła łańcuch, ale nie zawiera certyfikatu głównego. Dlatego większość czasu nie będziesz musiał importować całego łańcucha do magazynu kluczy. Powinieneś jednak jawnie ufać certyfikatowi głównemu. –

+0

@lestestead tak, zazwyczaj musisz zaimportować tylko główny urząd certyfikacji; odpowiedź edytowana. –

+0

Zaimportowałem certyfikat (wersja base64) do magazynu kluczy w katalogu 'lib \ security \ cacerts', ale java nadal podaje ten sam błąd. Po zaimportowaniu go do magazynu zaufanych certyfikatów systemu Windows Chrome przestał podawać błędy. Ale kiedy zrobiłem to za pomocą Java Keytool, nadal nie mogę się połączyć. – nurettin

6

ten jest generowany, gdy

... peer nie był w stanie zidentyfikować się (na przykład, nie ma certyfikat , konkretny pakiet szyfr używany nie obsługuje uwierzytelnianie lub uwierzytelnianie nie było wzajemnej ustanowiony podczas uzgadniania SSL ) ten wyjątek jest zgłaszany.

Prawdopodobnie przyczyną tego wyjątku (gdzie jest stacktrace) pokaże, dlaczego ten wyjątek został zgłoszony. Najprawdopodobniej domyślny magazyn kluczy dostarczany z Javą nie zawiera (i nie ufał) certyfikatu głównego używanego TTP.

Odpowiedzią jest pobranie certyfikatu głównego (np. Z połączenia SSL przeglądarki), zaimportowanie go do pliku cacerts i zaufanie do niego za pomocą keytool, które jest dostarczane przez Java JDK. W przeciwnym razie będziesz musiał programowo przypisać inny magazyn zaufania.

0

Nie jestem programistą java, ale korzystałem z aplikacji java do testowania interfejsu RESTful API. Aby naprawić błąd, musiałem zainstalować pośrednie certyfikaty na serwerze internetowym, aby błąd zniknął. Używałem lighttpd, oryginalny certyfikat został zainstalowany na serwerze IIS. Mam nadzieję, że to pomoże. To były certyfikaty, których brakowało mi na serwerze.

  • CA.crt
  • UTNAddTrustServer_CA.crt
  • AddTrustExternalCARoot.crt
0
keytool -import -v -alias cacerts -keystore cacerts.jks -storepass changeit -file C:\cacerts.cer 
Powiązane problemy