W końcu udało mi się rozwiązać wszystkie problemy, więc odpowiem na własne pytanie. Są to ustawienia / pliki, którymi zarządzałem, aby rozwiązać konkretny problem;
The kluczy klienta jest PKCS # 12 Format pliku zawierającego
- Publiczny certyfikat klienta (w tym przypadku podpisany przez samopodpisany urząd certyfikacji)
- Klucz prywatny klienta
Aby go wygenerować, użyłem pkcs12
na przykład polecenia OpenSSL ;
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "Whatever"
Wskazówka: upewnij się, że masz najnowszą wersję OpenSSL, a nie wersję 0.9.8h, ponieważ wydaje się, że zawiera błąd, który nie pozwala poprawnie wygenerować plików PKCS # 12.
Ten plik PKCS # 12 zostanie wykorzystany przez klienta Java do przedstawienia certyfikatu klienta na serwerze, gdy serwer wyraźnie zażąda od klienta uwierzytelnienia. Zobacz artykuł Wikipedii na temat TLS, aby zobaczyć, jak działa protokół uwierzytelniania certyfikatu klienta (wyjaśnia również, dlaczego potrzebujemy tutaj klucza prywatnego klienta).
Przez zaufanych klienta jest proste JKS Format pliku zawierającego korzeniowych lub certyfikaty pośredniego urzędu certyfikacji . Te certyfikaty CA określą, z którymi punktami końcowymi będziesz mógł się komunikować, w tym przypadku pozwoli Twojemu klientowi połączyć się z dowolnym serwerem, który przedstawia certyfikat, który został podpisany przez jeden z CA urzędu certyfikacji.
Aby go wygenerować, możesz na przykład użyć standardowego narzędzia Java.
keytool -genkey -dname "cn=CLIENT" -alias truststorekey -keyalg RSA -keystore ./client-truststore.jks -keypass whatever -storepass whatever
keytool -import -keystore ./client-truststore.jks -file myca.crt -alias myca
Korzystając z tego magazynu zaufanych certyfikatów, Twój klient będzie próbował przeprowadzić pełny uścisk protokołu SSL ze wszystkimi serwerami, które przedstawią certyfikat podpisany przez urząd certyfikacji myca.crt
.
Powyższe pliki są przeznaczone wyłącznie dla klienta. Jeśli chcesz również skonfigurować serwer, serwer potrzebuje własnych plików kluczy i magazynu zaufanych certyfikatów. Na tej stronie można znaleźć świetne instrukcje konfiguracji w pełni działającego przykładu zarówno dla klienta Java, jak i serwera (za pomocą Tomcat) .
Problemy / uwagi / wskazówki
- Uwierzytelnianie certyfikatu klienta może być wymuszone tylko przez serwer.
- ( Ważne! ) Gdy serwer zażąda certyfikatu klienta (w ramach uzgadniania TLS), dostarczy również listę zaufanych urzędów certyfikacji jako część żądania certyfikatu. Kiedy certyfikat klienta, który chcesz przedstawić do uwierzytelnienia, nie jest podpisany przez jeden z tych urzędów certyfikacji, w ogóle nie zostanie przedstawiony (moim zdaniem jest to dziwne zachowanie, ale jestem pewien, że istnieje ku temu powód). To była główna przyczyna moich problemów, ponieważ druga strona nie skonfigurowała odpowiednio swojego serwera, aby akceptował mój samopodpisany certyfikat klienta i założyliśmy, że problem leży po mojej stronie z powodu niepoprawnego podania certyfikatu klienta w żądaniu.
- Uzyskaj Wireshark. Ma świetną analizę pakietów SSL / HTTPS i będzie ogromną pomocą przy debugowaniu i znajdowaniu problemu. Jest podobny do,
-Djavax.net.debug=ssl
ale jest bardziej uporządkowany i (prawdopodobnie) łatwiejszy do interpretacji, jeśli nie czujesz się komfortowo z wynikiem debugowania Java SSL.
Korzystanie z biblioteki httpclient Apache jest całkowicie możliwe. Jeśli chcesz użyć klienta httpclient, po prostu zastąp docelowy adres URL odpowiednikiem HTTPS i dodaj następujące argumenty JVM (takie same dla każdego innego klienta, niezależnie od biblioteki, której chcesz używać do wysyłania / odbierania danych przez HTTP / HTTPS) :
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.keyStore=client.p12
-Djavax.net.ssl.keyStorePassword=whatever
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.trustStore=client-truststore.jks
-Djavax.net.ssl.trustStorePassword=whatever