wtorek, 27 stycznia 2009

Unable to find valid certification path to requested target

--------------------------

Unable to find valid certification path in English

--------------------------

Jeśli nawiązujecie połączenie z usługą sieciową (web service) poprzez https (czyli z użyciem SSL) natrafić możecie na dość znany wyjątek:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target


Oznacza to tyle, że łączymy się z usługą przez SSL i nie znamy lub nie akceptujemy certyfikatu uwierzytelniającego tej usługi. Gdybyśmy łączyli się ze stroną www przez przeglądarkę, wyskoczyłoby nam znane okienko informujące nas, że połączenie nie może być nawiązane, gdyż (cytując Firefox'a) "certyfikat nie jest zaufany, ponieważ certyfikat wystawcy nie jest zaufany.". Wtedy najczęściej klikamy "Zaufaj witrynie" lub "Potwierdź wyjątek bezpieczeństwa" i już możemy oglądać naszą witrynę w bezpiecznym połączeniu SSL.

W przypadku programów napisanych w języku Java, nie mamy pewności, że zawsze po drugiej stronie aplikacji będzie siedział użytkownik, który kliknie "Potwierdź wyjątek bezpieczeństwa". Dlatego, aby aplikacja łączyła się zawsze poprawnie przez SSL, należy wcześniej ten "wyjątek" potwierdzić.
Najprostszym sposobem jest wygenerowanie tak zwanego keystore'a dla danego certyfikatu i potem użycie go w aplikacji. Robi się to w sposób następujący:

1. wygenerowanie pliku .cer

Jest to plik reprezentujący certyfikat. Często jest udostępniany przez firmę, z której serwerem łączymy się przez SSL. Jeśli jednak nie mamy do niego dostępu najprościej go zdobyć wchodząc na dany adres usługi (ten adres uslugi, z która później ma łączyć się nasza aplikacja) poprzez dowolną przeglądarkę. Potwierdzić certyfikat, następnie odnaleźć go w ustawieniach przeglądarki i na końcu wyeksportować do pliku .cer. Większość przeglądarek (na pewno Firefox i Opera) udostępniają taką funkcjonalność.

2. wygenerować keystore

Keystore możemy wygenerować wraz z narzędziem keytool, które dostępne mamy zawsze wraz z naszym JDK. Wywołujemy ten program w konsoli w sposób następujący:

keytool -import -trustcacerts -keystore cacerts -storepass twoje_haslo -noprompt -file cert.cer

gdzie: -file to wygenerowany w punkcie pierwszym plik .cer, -keystore to nazwa pliku keystore (może być dowolna), -storepass to hasło które będzie używane wraz z danym keystorem.

3. ustawienie propertiesów

Na końcu należy wygenerowany plik keystore (w naszym przypadku nazywa się cacerts) wrzucić do katalogu naszej aplikacji, a w samym kodzie ustawić dwa dodatkowe propertiesy:


System.setProperty("javax.net.ssl.trustStore", "cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "twoje_haslo");


Od tego momentu powinniśmy bez problemów łączyć się z dowolną bramką webservicową (czy też jakąkolwiek usługą w sieci) poprzez SSL.

Referencje:
http://wso2.org/forum/thread/3018
http://blogs.sun.com/andreas/entry/no_more_unable_to_find

7 komentarzy:

Anonimowy pisze...

Dziękuję - przydało się w skonfigurowaniu wywołania usługi z certyfikatem klienta z Oracle'a.
Pozdrawiam - Michał T.

Mariusz Borkowski pisze...

Ekstra, bardzo mi pomogło przy wołaniu webserwisu po https!

Radek pisze...

Po przejściu tej procedury i wywołaniu WebServisu wylądowałem na takim wyjątku:

java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Gdzie popełniłem błąd?

Radek pisze...

Po przejściu tej procedury i wywołaniu WebServisu wylądowałem na takim wyjątku:

java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Gdzie popełniłem błąd?

Marciszka pisze...

mam taki sam problem, jak Radek:

javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

co poradzić ???????

Marciszka pisze...

udało się :) miałam duże szczęście - pośród dziesiątków linków tu: http://boards.developerforce.com/t5/Java-Development/login-trustAnchors-parameter-must-be-non-empty/td-p/302291 trafiłam na rozwiązanie problemu!

POWODZENIA !

Anonimowy pisze...

konkretnie i rzeczowo, dzieki!