Tworzę aplikację Java, która wysyła zapytania do interfejsu API REST na zdalnym serwerze za pośrednictwem protokołu HTTP. Ze względów bezpieczeństwa ta komunikacja powinna zostać przełączona na HTTPS.
Teraz, gdy Let's Encrypt rozpoczęło swoją publiczną wersję beta, chciałbym wiedzieć, czy Java obecnie działa (lub jest potwierdzona, że będzie działać w przyszłości) z ich certyfikatami domyślnie.
Let's Encrypt otrzymało pośredni podpis krzyżowy przez IdenTrust , co powinno być dobrą wiadomością. Jednak nie mogę znaleźć żadnego z tych dwóch w danych wyjściowych tego polecenia:
keytool -keystore "..\lib\security\cacerts" -storepass changeit -list
Wiem, że zaufane urzędy certyfikacji można dodać ręcznie na każdym komputerze, ale ponieważ moja aplikacja powinna być bezpłatna do pobrania i wykonywalna bez dalszej konfiguracji, szukam rozwiązań, które działają „po wyjęciu z pudełka”. Czy masz dla mnie dobrą wiadomość?
Odpowiedzi:
[ Aktualizacja 2016-06-08 : Według https://bugs.openjdk.java.net/browse/JDK-8154757, IdenTrust CA zostanie uwzględniony w Oracle Java 8u101.]
[ Aktualizacja 2016-08-05 : wydano Java 8u101 i rzeczywiście zawiera ona IdenTrust CA: informacje o wersji ]
Tak. Certyfikat Let's Encrypt to zwykły certyfikat klucza publicznego. Java to obsługuje (zgodnie z Let's Encrypt Certificate Compatibility , dla Java 7> = 7u111 i Java 8> = 8u101).
Nie / to zależy od JVM. Truststore Oracle JDK / JRE do 8u66 nie zawiera ani konkretnego urzędu certyfikacji Let's Encrypt, ani urzędu certyfikacji IdenTrust, który go podpisał.
new URL("https://letsencrypt.org/").openConnection().connect();
na przykład powodujejavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException
.Można jednak udostępnić własny walidator / zdefiniować niestandardowy magazyn kluczy zawierający wymagany główny ośrodek certyfikacji lub zaimportować certyfikat do magazynu zaufanych certyfikatów maszyny JVM.
https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/10 również omawia ten temat.
Oto przykładowy kod, który pokazuje, jak dodać certyfikat do domyślnego magazynu zaufanych certyfikatów w czasie wykonywania. Musisz tylko dodać certyfikat (wyeksportowany z przeglądarki Firefox jako .der i wstawić ścieżkę klas)
Na podstawie Jak mogę uzyskać listę zaufanych certyfikatów głównych w Javie? i http://developer.android.com/training/articles/security-ssl.html#UnknownCa
źródło
isrgrootx1.der
ilets-encrypt-x1-cross-signed.der
, ale żaden z nich nie wydaje się być właściwy.https://helloworld.letsencrypt.org
na przykład i sprawdź łańcuch certyfikatów w przeglądarce (klikając zieloną ikonę). Do tego potrzebny jest certyfikat specyficzny dla witryny, pośredni certyfikat X1 (podpisany krzyżowo przez IdenTrust) lub certyfikat DSTRootCAX3.ISRG Root X1
Nie działa na stronie helloworld ponieważ nie jest w łańcuchu, który jest alternatywą łańcuch. Użyłbym DSTRoot, po prostu wyeksportowanego przez przeglądarkę, ponieważ nigdzie nie widziałem go do pobrania.javax.net.ssl.trustStore
właściwość systemową, ale -1 za to ustawienie wartości domyślnej maszyny JVMSSLContext
. Lepiej byłoby utworzyć nową,SSLSocketFactory
a następnie użyć jej dla różnych połączeń (np.HttpUrlConnection
), Zamiast zastępować konfigurację SSL dla całej maszyny wirtualnej. (Zdaję sobie sprawę, że ta zmiana jest skuteczna tylko dla działającej maszyny JVM i nie utrzymuje się ani nie wpływa na inne programy. Myślę tylko, że lepszą praktyką programistyczną jest wyraźne określenie, gdzie ma zastosowanie twoja konfiguracja.)Wiem, że OP poprosił o rozwiązanie bez lokalnych zmian konfiguracji, ale na wypadek, gdybyś chciał trwale dodać łańcuch zaufania do magazynu kluczy:
źródło: https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/13
źródło
Szczegółowa odpowiedź dla tych z nas, którzy chcą dokonać lokalnych zmian konfiguracyjnych, które obejmują utworzenie kopii zapasowej pliku konfiguracyjnego:
1. Sprawdź, czy działa przed zmianami
Jeśli nie masz jeszcze programu testowego, możesz użyć mojego programu ping SSLPing java, który testuje uzgadnianie TLS (będzie działać z dowolnym portem SSL / TLS, nie tylko HTTPS). Użyję gotowego pliku SSLPing.jar, ale czytanie kodu i samodzielne tworzenie go to szybkie i łatwe zadanie:
Ponieważ moja wersja Java jest starsza niż 1.8.0_101 (nie została wydana w momencie pisania tego tekstu), certyfikat Let's Encrypt nie będzie domyślnie weryfikowany. Zobaczmy, jak wygląda awaria przed zastosowaniem poprawki:
2. Zaimportuj certyfikat
Pracuję na Mac OS X z ustawioną zmienną środowiskową JAVA_HOME. Późniejsze polecenia przyjmą, że ta zmienna jest ustawiona dla modyfikowanej instalacji Java:
Utwórz kopię zapasową pliku cacerts, który będziemy modyfikować, aby móc cofnąć wszelkie zmiany bez ponownej instalacji JDK:
Pobierz certyfikat podpisujący, który musimy zaimportować:
Wykonaj import:
3. Sprawdź, czy działa po zmianach
Sprawdź, czy Java jest teraz zadowolona z połączenia z portem SSL:
źródło
W przypadku JDK, które jeszcze nie obsługują certyfikatów Let's Encrypt, możesz je dodać do JDK
cacerts
po tym procesie (dzięki temu ).Pobierz wszystkie certyfikaty z https://letsencrypt.org/certificates/ (wybierz format der ) i dodawaj je jeden po drugim za pomocą tego rodzaju polecenia (przykład dla
letsencryptauthorityx1.der
):źródło