wtorek, 27 stycznia 2009

Unable to find valid certification path to requested target

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

Brak komentarzy: