web-dev-qa-db-fra.com

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

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. Est-ce que quelqu'un sait comment faire cela ou pourrait nous orienter dans la bonne direction? Merci!

9
user2072931

Vous ne pouvez pas faire ça avec keytool. Premièrement, keytool ne supporte pas du tout DH. Deuxièmement, keytool ne génère pas de paramètres par lui-même pour n'importe quel algorithme, seulement une clé privée/paire de clés. Troisièmement, lorsque keytool génère une paire de clés, il génère également un certificat auto-signé (qui parfois est ensuite remplacé par un "vrai" certificat émis par l'autorité de certification) et c'est impossible de générer un certificat auto-signé pour DH car DH ne signe pas. Vous pourriez écrire un programme Java très simple (environ 10 lignes) pour générer les paramètres DH. Mais cela ne vous ferait probablement aucun bien car:

Java n'accepte pas les paramètres DHE ici de toute façon. 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 le 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 en haut.) Java 8 JSSE vous permet de contrôler la size 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 plus tôt, par défaut DHE à 1024 bits, ce que la plupart des autorités considèrent comme assez fort même si faibledh.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 https://stackoverflow.com/questions/30352105/how-to-set-custom-dh-group-in-Java-sslengine-to-prevent-logjam-attack . Notez que si vous avez des Java clients avant Java 8, ils seront fail 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.

Activer ECDHE. JSSE dans Java 7 et versions ultérieures implémentent ECDHE, qui n'est pas soumis à un précalcul comme DHE, (normalement) en utilisant P-256, qui est plus que fort suffisant. (Bien que certaines personnes ne fassent pas confiance à any des courbes ECC du NIST parce que le NIST en général est influencé par la NSA, bien qu'aucune source ouverte à ma connaissance n'a montré de problème dans les courbes ECC spécifiquement.) Java 6 a en fait la partie JSSE pour ECDHE mais elle n'est activée que si la JVM a un crypto "fournisseur" pour les primitives ECC, ce que Java 6 n'a pas. bcprov - * - jdk15on from http://www.bouncycastle.org/ est un fournisseur JCE pour une gamme de Java primitives de chiffrement, y compris ECC, donc si vous ajoutez le pot à votre JRE/lib/ext Et ajoutez org.bouncycastle.jce.provider.BouncyCastleProvider À la liste dans JRE/lib/security/Java.security (Ou faites une Security.add/insertProvider() appropriée quelque part au début de votre code) Java 6 peut faire ECDHE . Bien sûr, si vous devez 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 préfèrent à DHE - c'est-à-dire, bonjour le navigateur liste les suites ECDHE avant les suites DHE de sorte 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ésactiver DHE. Vous pouvez configurer la liste de chiffrements dans l'attribut Connector pour exclure les chiffrements DHE; pendant que vous y êtes, excluez également staticDH et staticECDH qui sont inutiles, et (single) 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 comme $server/deploy/jbossweb/server.xml.

Essayez natif. Tomcat, qui comme je l'ai dit JbossWS a commencé, 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 a une option native compatible TC, et if il peut gérer la configuration des paramètres DH, puis utilisez openssl pour générer le Paramètres DH et instructions natives JbossWS pour les configurer.

13
dave_thompson_085

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

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

Si vous souhaitez fournir une combinaison différente, vous pouvez les spécifier dans jre/lib/security/Java.security avec le jdk.tls.server.defaultDHEParameters propriété de sécurité (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 avez utilisé openssl dhparam -out dhparam2048.pem 2048 pour générer une nouvelle paire, vous pouvez utiliser openssl dhparam -noout -text -check -in dhparam2048.pem pour 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 le : entre la représentation hexa 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, lorsque vous exécutez openssl s_client, je peux voir le premier 1024 bits ( ffffff ffffffffffc90f ... 5381ffffffffffffffff ) lors de la connexion à un Java 8 Serveur JSSE:

>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 (768bit) seraient "e9e642 ... 7a3daf" avec un long générateur "30470ad..529252" tel que défini dans ParameterCache .

4
eckes

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

Pour obtenir une longueur de clé DH éphémère supérieure à 768 bits, vous devez exécuter sur Java 8. 1024 est la nouvelle valeur par défaut, et vous pouvez aller jusqu'à 2048 en utilisant le jdk.tls.ephemeralDHKeySize (détails: personnalisation des touches 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.

3
David Hutchison