Comment générer de nouveaux paramètres Diffie-Hellman 2048 bits avec Java keytool?

9

Nous sommes des non-experts qui tentent - sans succès jusqu'à présent - de mettre à jour les paramètres de notre serveur Web (JBoss-5.1.0.GA) pour répondre aux normes Diffie-Hellman. Après avoir exécuté un test sur https://weakdh.org/sysadmin.html , on nous dit que nous devons "générer de nouveaux paramètres Diffie-Hellman de 2048 bits". Dans le passé, nous avons généré des clés avec Java keytool, mais nous n'avons pu trouver aucune information sur la génération d'un nouveau paramètre Diffie-Hellman de 2048 bits avec Java keytool. Quelqu'un sait-il comment procéder ou pourrait-il nous orienter dans la bonne direction? Je vous remercie!

user2072931
la source

Réponses:

13

Vous ne pouvez pas faire ça avec keytool. Tout d'abord, keytoolne prend pas en charge DH du tout. Deuxièmement, keytoolne génère pas de paramètres par lui-même pour aucun algorithme, uniquement une clé privée / paire de clés. Troisièmement, lorsqu'il keytoolgénère une paire de clés, il génère également un certificat auto-signé (qui est parfois remplacé par la suite par un "vrai" certificat émis par l'autorité de certification) et il est impossible de générer un certificat auto-signé pour DH car DH ne signe pas. Vous pouvez écrire un programme Java très simple (environ 10 lignes) pour générer des paramètres DH. Mais cela ne vous ferait probablement aucun bien car:

De toute façon, Java n'accepte pas les paramètres DHE ici. JbossWS (le serveur Web Jboss, plus tard Wildfly) est un fork de Tomcat, et utilise normalement l'implémentation Java de SSL / TLS, JSSE. Jusqu'à Java 7, JSSE utilise ses propres paramètres DHE qui sont de 768 bits, ce qui est trop faible. (Sauf pour les suites EXPORT où JSSE obéit à l'exigence RFC pour DH-512, qui est totalement cassée, mais les suites EXPORT sont de toute façon totalement cassées par conception, et désactivées par défaut dans Java 7 et versions ultérieures.) Java 8 JSSE vous permet de contrôler la taille des paramètres DHE, mais pas la valeur réelle.

Vos options (qui se chevauchent) sont:

Utilisez Java 8. JSSE dans Java 8, mais pas avant, par défaut DHE à 1024 bits, ce que la plupart des autorités considèrent comme assez fort même si faiblessedh.org ne le fait pas, et vous permet de spécifier plus, voir https://docs.oracle.com /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys et pour le fond /programming/30352105/how-to-set-custom-dh-group-in-java -sslengine-to-prevent-logjam-attack . Notez que si vous avez des clients Java avant Java 8, ils échoueront si le serveur utilise DHE sur 1024 bits. Je ne connais aucun autre client qui a ce problème, mais testez le vôtre avant de vous engager dans ce changement.

Activez ECDHE. JSSE dans Java 7 et versions ultérieures implémente ECDHE, qui n'est pas soumis à un pré-calcul comme DHE, (normalement) en utilisant P-256, qui est plus que suffisamment puissant. (Bien que certaines personnes ne fassent confiance à aucune des courbes ECC du NIST parce que le NIST en général est influencé par la NSA, bien qu'aucune source ouverte que je connaisse n'a montré de problème dans les courbes ECC en particulier.) Java 6 a en fait la partie JSSE pour ECDHE mais il n'est activé que si la JVM a un "fournisseur" de crypto pour les primitives ECC, ce que Java 6 n'a pas. bcprov - * - jdk15on de http://www.bouncycastle.org/ est un fournisseur JCE pour une gamme de primitives de chiffrement Java, y compris ECC, donc si vous ajoutez le pot à votre JRE/lib/extet ajoutez org.bouncycastle.jce.provider.BouncyCastleProviderà la liste dans JRE/lib/security/java.security(ou faites unSecurity.add/insertProvider()quelque part au début de votre code) Java 6 peut faire ECDHE. Bien sûr, si vous devriez avoir un Java 6 encore utilisé, c'est une question en soi.

Il y a quelques années, la prise en charge d'ECDHE dans les navigateurs et autres clients était incertaine, mais aujourd'hui, AFAIK tous les navigateurs à jour la prennent en charge et la préfèrent à DHE - c'est-à-dire que le navigateur répertorie les suites ECDHE avant les suites DHE afin que si le serveur implémente les deux, il doit choisir ECDHE. Les clients sans navigateur peuvent ne pas l'être; test pour être certain.

Désactivez DHE. Vous pouvez configurer la liste des chiffres dans l'attribut Connector pour exclure les chiffres DHE; pendant que vous y êtes, excluez également staticDH et staticECDH qui sont inutiles, et (unique) DES et (tous) "EXPORT" s'ils sont présents (Java 6). Cela signifie que les navigateurs et les clients qui ne font pas ECHDE seront bloqués avec plain-RSA et pas de secret en amont, mais au moins ils ont un secret "actuel". Je ne me souviens pas avec certitude, mais je pense que la configuration du connecteur 5.1 était encore quelque part $server/deploy/jbossweb/server.xml.

Essayez natif. Tomcat, qui, comme je l'ai dit, a commencé avec JbossWS, a une option pour implémenter HTTPS (SSL / TLS) en utilisant "native" aka "APR" qui est en fait OpenSSL à l'intérieur plutôt que JSSE. J'ai eu un succès mitigé à faire fonctionner cette option sur JbossWS, et je ne me souviens pas de la 5.1. Si votre JbossWS dispose d'une option native compatible TC et s'il peut gérer la configuration des paramètres DH, utilisez openssl pour générer les paramètres DH et les instructions natives JbossWS pour les configurer.

dave_thompson_085
la source
Merci pour cette excellente information. La réponse pour nous n'a finalement pas impliqué keytool, juste des changements dans notre fichier server.xml, mais je vais vérifier cette réponse.
user2072931
4

En fait, vous pouvez spécifier des paramètres DHE personnalisés avec des versions récentes de Java 8 . C'est indépendant de l'application (tant qu'elle utilise l'implémentation JSSE TLS).

Vous devez d'abord spécifier la taille de la clé DHE à utiliser ( -Djdk.tls.ephemeralDHKeySize=1024ou -Djdk.tls.ephemeralDHKeySize=2048). Sur le serveur, cela utilisera une combinaison générateur / prime prédéfinie pour DHE. Avec Java 8, seuls 1024 ou 2048 peuvent être utilisés, JDK 9 prendra en charge des tailles plus importantes .

Si vous souhaitez fournir une combinaison différente, vous pouvez les spécifier dans jre / lib / security / Java.security avec la jdk.tls.server.defaultDHEParameterspropriété security (depuis 8u51). Il prend une liste de paramètres (un pour chaque taille de clé utilisée) et il doit contenir le premier et le générateur (généralement 2 ou 5) en hexadécimal.

Si vous aviez l'habitude openssl dhparam -out dhparam2048.pem 2048de générer une nouvelle paire, vous pouvez utiliser openssl dhparam -noout -text -check -in dhparam2048.pempour lire et imprimer ce fichier en mode texte. Vous devrez copier et coller le texte dans les propriétés de sécurité Java (en utilisant tr -d ':'pour supprimer la :représentation hexadécimale openssl)

Voici un exemple (1024 bis uniquement):

>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.

Et cela se traduit par

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

Vous devez redémarrer le serveur et vérifier qu'il utilise réellement ce premier (et non celui par défaut) car le processus n'est pas simple, donc beaucoup de choses peuvent mal se passer. La valeur par défaut est définie dans la source , pour 2048 bits, le nombre premier provient du projet TLS FFDHE.

Par exemple, lors de l'exécution de openssl s_client, je peux voir le nombre premier de 1024 bits ( ffffff ffffffffffc90f ... 5381ffffffffffffffffff ) lors de la connexion à un serveur JSSE Java 8:

>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 ...

Au lieu de cela, vous devez voir vos paramètres personnalisés lors de l'installation.

Les paramètres par défaut pour Java 7 (768 bits) seraient "e9e642 ... 7a3daf" avec un long générateur "30470ad..529252" tel que défini dans ParameterCache .

eckes
la source
3

J'ai vécu ce même problème, mais de Glassfish.

Tout d'abord, je recommanderais (si vous le pouvez) de mettre une sorte de proxy inverse devant votre serveur JBoss car cela supprimera le lien entre la sécurité du chiffrement / certificat et la version de Java que vous exécutez.

Pour obtenir une longueur de clé DH éphémère supérieure à 768 bits, vous devez exécuter Java 8. 1024 est la nouvelle valeur par défaut, et vous pouvez aller jusqu'à 2048 en utilisant les jdk.tls.ephemeralDHKeySize(détails: personnalisation des clés DH ). D'après ce que j'ai pu trouver, il n'y a aucun concept de régénération des paramètres clés séparément en Java.

David Hutchison
la source
Merci pour cette suggestion d'alternative. Nous pourrons nous pencher sur cette question à l'avenir.
user2072931
Il y a maintenant, voir serverfault.com/a/798036/4591
eckes
pour glassfish / payara / payara-micro pour désactiver les chiffrements DHE ajouter <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>au <protocol name="http-listener-2" security-enabled="true">connecteur SSL
Markus