Ich entwickle eine Java-Anwendung, die eine REST-API auf einem Remote-Server über HTTP abfragt. Aus Sicherheitsgründen sollte diese Kommunikation auf HTTPS umgestellt werden.
Nachdem Let's Encrypt die öffentliche Beta gestartet hat, möchte ich wissen, ob Java derzeit standardmäßig mit seinen Zertifikaten funktioniert (oder bestätigt wird, dass es in Zukunft funktioniert).
Lassen Sie uns Encrypt von IdenTrust mit einem Zwischensignal versehen , was eine gute Nachricht sein sollte. Ich kann jedoch keine dieser beiden in der Ausgabe dieses Befehls finden:
keytool -keystore "..\lib\security\cacerts" -storepass changeit -list
Ich weiß, dass vertrauenswürdige Zertifizierungsstellen manuell auf jedem Computer hinzugefügt werden können. Da meine Anwendung jedoch ohne weitere Konfiguration kostenlos heruntergeladen und ausgeführt werden kann, suche ich nach Lösungen, die "out of the box" funktionieren. Hast du gute Nachrichten für mich?
Antworten:
[ Update 2016-06-08 : Laut https://bugs.openjdk.java.net/browse/JDK-8154757 wird die IdenTrust-Zertifizierungsstelle in Oracle Java 8u101 enthalten sein.]
[ Update - 2016.08.05 : Java 8u101 wurde veröffentlicht und in der Tat die Identrust CA enthält: Release Notes ]
Ja. Das Let's Encrypt-Zertifikat ist nur ein reguläres Zertifikat mit öffentlichem Schlüssel. Java unterstützt dies (laut Let's Encrypt Certificate Compatibility für Java 7> = 7u111 und Java 8> = 8u101).
Nein / es hängt von der JVM ab. Der Truststore von Oracle JDK / JRE bis 8u66 enthält weder die Let's Encrypt-Zertifizierungsstelle noch die IdenTrust-Zertifizierungsstelle, die ihn kreuzsigniert hat.
new URL("https://letsencrypt.org/").openConnection().connect();
zum Beispiel ergibtjavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException
.Sie können jedoch Ihren eigenen Validator bereitstellen / einen benutzerdefinierten Schlüsselspeicher definieren, der die erforderliche Stammzertifizierungsstelle enthält, oder das Zertifikat in den JVM-Truststore importieren.
https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/10 behandelt das Thema ebenfalls.
Hier ist ein Beispielcode, der zeigt, wie Sie zur Laufzeit ein Zertifikat zum Standard-Truststore hinzufügen. Sie müssen nur das Zertifikat hinzufügen (aus Firefox als .der exportiert und in den Klassenpfad eingefügt).
Basierend auf Wie kann ich eine Liste vertrauenswürdiger Stammzertifikate in Java abrufen? und http://developer.android.com/training/articles/security-ssl.html#UnknownCa
quelle
isrgrootx1.der
undlets-encrypt-x1-cross-signed.der
, aber keiner von ihnen scheint der richtige zu sein.https://helloworld.letsencrypt.org
Beispiel zu und überprüfen Sie die Zertifikatskette im Browser (klicken Sie auf das grüne Symbol). Für dieses benötigen Sie entweder das standortspezifische Zertifikat, das X1-Zwischenzertifikat (von IdenTrust gekreuzt) oder das DSTRootCAX3-Zertifikat. DasISRG Root X1
funktioniert nicht für die helloworld-Site, da es nicht in der Kette ist, das ist die alternative Kette. Ich würde den DSTRoot verwenden, der einfach über den Browser exportiert wird, da ich ihn nirgendwo zum Download gesehen habe.javax.net.ssl.trustStore
Systemeigenschaft betrügt , sondern -1 zum Festlegen der Standardeinstellung der JVMSSLContext
. Es ist besser, eine neue zu erstellenSSLSocketFactory
und diese dann für verschiedene Verbindungen (z. B.HttpUrlConnection
) zu verwenden, als die VM-weite SSL-Konfiguration zu ersetzen. (Mir ist klar, dass diese Änderung nur für die laufende JVM wirksam ist und andere Programme nicht beibehält oder beeinflusst. Ich denke nur, dass es eine bessere Programmierpraxis ist, explizit anzugeben, wo Ihre Konfiguration angewendet wird.)Ich weiß, dass das OP nach einer Lösung ohne lokale Konfigurationsänderungen gefragt hat, aber falls Sie die Vertrauenskette dauerhaft zum Keystore hinzufügen möchten:
Quelle: https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/13
quelle
Detaillierte Antwort für diejenigen von uns, die bereit sind, lokale Konfigurationsänderungen vorzunehmen, einschließlich der Sicherung der Konfigurationsdatei:
1. Testen Sie vor den Änderungen, ob es funktioniert
Wenn Sie noch kein Testprogramm haben, können Sie mein Java-SSLPing-Ping-Programm verwenden, das den TLS-Handshake testet (funktioniert mit jedem SSL / TLS-Port, nicht nur mit HTTPS). Ich werde die vorgefertigte SSLPing.jar verwenden, aber das Lesen des Codes und das Erstellen selbst ist eine schnelle und einfache Aufgabe:
Da meine Java-Version früher als 1.8.0_101 ist (zum Zeitpunkt dieses Schreibens noch nicht veröffentlicht), wird ein Let's Encrypt-Zertifikat standardmäßig nicht überprüft. Lassen Sie uns sehen, wie ein Fehler aussieht, bevor Sie das Update anwenden:
2. Importieren Sie das Zertifikat
Ich arbeite unter Mac OS X mit der Umgebungsvariablen JAVA_HOME. Spätere Befehle setzen voraus, dass diese Variable für die Java-Installation festgelegt ist, die Sie ändern:
Erstellen Sie eine Sicherungskopie der Cacerts-Datei, die wir ändern werden, damit Sie alle Änderungen rückgängig machen können, ohne das JDK neu zu installieren:
Laden Sie das zu importierende Signaturzertifikat herunter:
Führen Sie den Import durch:
3. Stellen Sie sicher, dass es nach den Änderungen funktioniert
Stellen Sie sicher, dass Java jetzt gerne eine Verbindung zum SSL-Port herstellt:
quelle
Für JDK, die Let's Encrypt-Zertifikate noch nicht unterstützen, können Sie diese nach
cacerts
diesem Vorgang (dank dessen ) zum JDK hinzufügen .Laden Sie alle Zertifikate unter https://letsencrypt.org/certificates/ herunter (wählen Sie das der- Format) und fügen Sie sie nacheinander mit diesem Befehl hinzu (Beispiel für
letsencryptauthorityx1.der
):quelle