Wie generiere ich neue 2048-Bit-Diffie-Hellman-Parameter mit Java Keytool?

9

Wir sind keine Experten, die - bisher erfolglos - versuchen, unsere Einstellungen für den Webserver (JBoss-5.1.0.GA) so zu aktualisieren, dass sie den Diffie-Hellman-Standards entsprechen. Nachdem wir einen Test unter https://weakdh.org/sysadmin.html ausgeführt haben , wird uns mitgeteilt, dass wir "neue 2048-Bit-Diffie-Hellman-Parameter generieren müssen". In der Vergangenheit haben wir Schlüssel mit Java-Keytool generiert, aber wir konnten keine Informationen zum Generieren eines neuen 2048-Bit-Diffie-Hellman-Parameters mit Java-Keytool finden. Weiß jemand, wie das geht oder könnte er uns in die richtige Richtung weisen? Danke!

user2072931
quelle

Antworten:

13

Mit Keytool geht das nicht. Erstens keytoolunterstützt DH überhaupt nicht. Zweitens werden keytoolfür keinen Algorithmus selbst Parameter generiert , sondern nur ein privater Schlüssel / ein Schlüsselpaar. Drittens wird beim keytoolGenerieren eines Schlüsselpaares auch ein selbstsigniertes Zertifikat generiert (das manchmal später durch ein "echtes" CA-ausgestelltes Zertifikat ersetzt wird), und es ist unmöglich, ein selbstsigniertes Zertifikat für DH zu generieren, da DH nicht signiert. Sie könnten ein sehr einfaches Java-Programm (ca. 10 Zeilen) schreiben, um DH-Parameter zu generieren. Aber es würde dir wahrscheinlich nichts nützen, weil:

Java akzeptiert hier sowieso keine DHE-Parameter. JbossWS (der Jboss-Webserver, später Wildfly) ist eine Abzweigung von Tomcat und verwendet normalerweise die Java-Implementierung von SSL / TLS, JSSE. Bis Java 7 verwendet JSSE seine eigenen DHE-Parameter, die 768-Bit sind und unannehmbar schwach sind. (Mit Ausnahme der EXPORT-Suiten, in denen JSSE die RFC-Anforderungen für DH-512 erfüllt, die völlig fehlerhaft sind, die EXPORT-Suiten jedoch ohnehin völlig fehlerhaft sind und in Java 7 standardmäßig deaktiviert sind.) Java 8 JSSE ermöglicht dies Steuern Sie die Größe der DHE-Parameter, jedoch nicht den tatsächlichen Wert.

Ihre (einige überlappende) Optionen sind:

Verwenden Sie Java 8. JSSE in Java 8, jedoch nicht früher, setzt DHE standardmäßig auf 1024 Bit, was die meisten Behörden als stark genug betrachten, obwohl dies bei schwachdh.org nicht der Fall ist, und ermöglicht es Ihnen, weitere Angaben zu machen (siehe https://docs.oracle.com) /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys und für den Hintergrund /programming/30352105/how-to-set-custom-dh-group-in-java -sslengine-to-verhindern-logjam-Angriff . Beachten Sie, dass Java- Clients vor Java 8 fehlschlagen, wenn der Server DHE über 1024 Bit verwendet. Ich kenne keine anderen Kunden, die dieses Problem haben, aber testen Sie Ihre, bevor Sie sich zu dieser Änderung verpflichten.

Aktivieren Sie ECDHE. JSSE in Java 7 und höher implementiert ECDHE, für das keine Vorberechnung wie DHE erforderlich ist, (normalerweise) mit P-256, das mehr als stark genug ist. (Obwohl einige Leute keiner der NIST-ECC-Kurven vertrauen, weil NIST im Allgemeinen von NSA beeinflusst wird, obwohl kein mir bekanntes Open Source ein Problem in den ECC-Kurven speziell gezeigt hat.) Java 6 hat tatsächlich den JSSE-Teil für ECDHE Es ist jedoch nur aktiviert, wenn die JVM einen Krypto "Provider" für ECC-Grundelemente hat, was Java 6 nicht tut. bcprov - * - jdk15on von http://www.bouncycastle.org/ ist ein JCE-Anbieter für eine Reihe von Java-Krypto- Grundelementen, einschließlich ECC. Wenn Sie also das Glas zu Ihrem JRE/lib/exthinzufügen org.bouncycastle.jce.provider.BouncyCastleProviderund zur Liste hinzufügen JRE/lib/security/java.security(oder eine geeignete Option ausführen)Security.add/insertProvider()irgendwo früh in Ihrem Code) Java 6 kann ECDHE ausführen. Ob Sie Java 6 noch verwenden sollten, ist natürlich eine Frage für sich.

Vor ein paar Jahren war die Unterstützung für ECDHE in Browsern und anderen Clients zweifelhaft, aber heute unterstützen AFAIK alle aktuellen Browser dies und ziehen es DHE vor - das heißt, der Browser listet die ECDHE-Suiten vor den DHE-Suiten auf Wenn der Server beide implementiert, sollte er ECDHE wählen. Nicht-Browser-Clients möglicherweise nicht; Test, um sicher zu sein.

Deaktivieren Sie DHE. Sie können die Liste der Chiffren im Connector-Attribut so konfigurieren, dass DHE-Chiffren ausgeschlossen werden. Wenn Sie gerade dabei sind, schließen Sie auch staticDH und staticECDH aus, die unbrauchbar sind, sowie (einzelnes) DES und (alle) "EXPORT", falls vorhanden (Java 6). Dies bedeutet, dass Browser und Clients, die ECHDE nicht ausführen, mit einfachem RSA und ohne Weiterleitungsgeheimnis nicht weiterkommen, aber zumindest "aktuelle" Geheimhaltung haben. Ich erinnere mich nicht sicher, aber ich denke, 5.1 Connector Konfiguration war immer noch irgendwo wie $server/deploy/jbossweb/server.xml.

Versuchen Sie es mit Native. Tomcat, von dem aus JbossWS gestartet ist, hat die Option, HTTPS (SSL / TLS) mithilfe von "nativ" oder "APR" zu implementieren, bei dem es sich tatsächlich um OpenSSL innerhalb von JSSE handelt. Ich hatte gemischte Erfolge damit, diese Option für JbossWS zum Laufen zu bringen, und erinnere mich nicht an 5.1. Wenn Ihr JBossWS hat eine tragfähige TC-native Option, und wenn es DH Parameter Konfiguration umgehen kann, dann OpenSSL verwenden , um die DH - Parameter und die JBossWS-native Anweisungen zu erzeugen , um sie zu konfigurieren.

dave_thompson_085
quelle
Vielen Dank für diese tolle Information. Die Antwort für uns beinhaltete letztendlich kein Keytool, sondern nur Änderungen an unserer Datei server.xml, aber ich werde diese Antwort überprüfen.
user2072931
4

Tatsächlich können Sie mit aktuellen Java 8-Versionen benutzerdefinierte DHE-Parameter angeben . Dies ist unabhängig von der Anwendung (sofern die JSSE TLS-Implementierung verwendet wird).

Sie müssen zuerst die Größe des zu verwendenden DHE-Schlüssels ( -Djdk.tls.ephemeralDHKeySize=1024oder -Djdk.tls.ephemeralDHKeySize=2048) angeben . Auf dem Server wird eine vordefinierte Generator / Prime-Kombination für DHE verwendet. Mit Java 8 können nur 1024 oder 2048 verwendet werden, JDK 9 unterstützt größere Größen .

Wenn Sie eine andere Kombination bereitstellen möchten, können Sie diese in jre / lib / security / Java.security mit der jdk.tls.server.defaultDHEParametersEigenschaft security (seit 8u51) angeben. Es enthält eine Liste von Parametern (einen für jede verwendete Schlüsselgröße) und muss die Primzahl und den Generator (normalerweise 2 oder 5) als Hex enthalten.

Wenn Sie openssl dhparam -out dhparam2048.pem 2048ein neues Paar generiert haben, können Sie openssl dhparam -noout -text -check -in dhparam2048.pemdiese Datei im Textmodus lesen und drucken. Sie müssen den Text kopieren und in die Java-Sicherheitseigenschaften einfügen ( tr -d ':'um die :zwischen den openssl-Hex-Darstellungen zu entfernen ).

Hier ist ein Beispiel (nur 1024 bis):

>openssl dhparam -in p -check -text -noout | tr -d ':'
PKCS#3 DH Parameters: (1024 bit)
    prime:
       00f7a63b59edcc43a43df12077f0e9
        14129c20a73cef95f919896e608ebc
        8722776c948765bbbf61542e118329
        6c6ea74ecbded3a93aff77a062aba4
        fcf04fc01030e65077f5a802605058
        65b836368dd5ea389d77691fac0f2c
        f7a161c51c8e97ddecb3cf7f872b0c
        cfaf54373d5203edcabc575e871bb1
        107ec2f30c78ebf403
    generator: 2 (0x2)
DH parameters appear to be ok.

Und das ergibt

jdk.tls.server.defaultDHEParameters= \
    { \
        00f7a63b59edcc43a43df12077f0e9 \
        14129c20a73cef95f919896e608ebc \
        8722776c948765bbbf61542e118329 \
        6c6ea74ecbded3a93aff77a062aba4 \
        fcf04fc01030e65077f5a802605058 \
        65b836368dd5ea389d77691fac0f2c \
        f7a161c51c8e97ddecb3cf7f872b0c \
        cfaf54373d5203edcabc575e871bb1 \
        107ec2f30c78ebf403, 2 }

Sie sollten den Server neu starten und sicherstellen, dass er tatsächlich diese Primzahl verwendet (und nicht die Standardprime), da der Prozess nicht einfach ist. Daher kann viel schief gehen. Die Standardeinstellung ist in der Quelle definiert . Für 2048 Bit stammt die Primzahl aus dem TLS FFDHE-Entwurf.

Wenn Sie beispielsweise openssl s_client ausführen, wird beim Herstellen einer Verbindung zu einem Java 8 JSSE-Server die 1024-Bit-Primzahl ( ffffff ffffffffffc90f ... 5381ffffffffffffffffff ) angezeigt :

>openssl s_client -msg -cipher DHE-RSA-AES128-SHA256 -connect localhost:1234
...
<<< TLS 1.2 Handshake [length 018f], ServerKeyExchange
0c 00 01 8b 00 80 ff ff ff ff ff ff ff ff c9 0f
da a2 21 68 c2 34 c4 c6 62 8b 80 dc 1c d1 29 02
4e 08 8a 67 cc 74 02 0b be a6 3b 13 9b 22 51 4a
08 79 8e 34 04 dd ef 95 19 b3 cd 3a 43 1b 30 2b
0a 6d f2 5f 14 37 4f e1 35 6d 6d 51 c2 45 e4 85
b5 76 62 5e 7e c6 f4 4c 42 e9 a6 37 ed 6b 0b ff
5c b6 f4 06 b7 ed ee 38 6b fb 5a 89 9f a5 ae 9f
24 11 7c 4b 1f e6 49 28 66 51 ec e6 53 81 ff ff
ff ff ff ff ff ff 00 01 02 ...

Stattdessen müssen Sie bei der Installation Ihre benutzerdefinierten Parameter sehen.

Die Standardparameter für Java 7 (768 Bit) wären "e9e642 ... 7a3daf" mit einem langen Generator "30470ad..529252", wie im ParameterCache definiert .

eckes
quelle
3

Ich habe das gleiche Problem durchgemacht, aber von Glassfish.

Erstens würde ich empfehlen (wenn Sie können), eine Art Reverse-Proxy vor Ihren JBoss-Server zu stellen, da dadurch die Verbindung zwischen der Verschlüsselungs- / Zertifikatsicherheit und der von Ihnen ausgeführten Java-Version entfernt wird.

Um eine größere Ephemeral DH-Schlüssellänge als 768 Bit zu erhalten, müssen Sie Java 8 ausführen. 1024 ist die neue Standardeinstellung, und Sie können mit den jdk.tls.ephemeralDHKeySize(Details: Anpassen von DH-Schlüsseln ) bis zu 2048 gehen . Nach allem, was ich finden konnte, gibt es in Java kein Konzept, die Schlüsselparameter separat zu regenerieren.

David Hutchison
quelle
Vielen Dank für diesen Vorschlag einer Alternative. Wir werden dies möglicherweise in Zukunft untersuchen.
user2072931
Es gibt jetzt, siehe serverfault.com/a/798036/4591
eckes
Damit Glassfish / Payara / Payara-Micro die DHE-Chiffren deaktiviert, fügen Sie <ssl tls-enabled="false" classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" tls11-enabled="false" cert-nickname="s1as" ssl3-tls-ciphers="+TLS_RSA_WITH_AES_256_CBC_SHA,+TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA256,+TLS_ECDH_RSA_WITH_AES_256_GCM_SHA256"></ssl>sie dem <protocol name="http-listener-2" security-enabled="true">SSL-Anschluss hinzu
Markus