Как сгенерировать новые 2048-битные параметры Диффи-Хеллмана с помощью Java keytool?

9

Мы не являемся экспертами и пока безуспешно пытаемся обновить настройки нашего веб-сервера (JBoss-5.1.0.GA), чтобы они соответствовали стандартам Диффи-Хеллмана. После запуска теста на https://weakdh.org/sysadmin.html нам говорят, что нам нужно «сгенерировать новые 2048-битные параметры Диффи-Хеллмана». В прошлом мы генерировали ключи с помощью Java keytool, но нам не удалось найти какую-либо информацию о генерации нового 2048-битного параметра Диффи-Хеллмана с помощью Java keytool. Кто-нибудь знает, как это сделать, или может указать нам правильное направление? Спасибо!

user2072931
источник

Ответы:

13

Вы не можете сделать это с помощью keytool. Во-первых, keytoolне поддерживает DH вообще. Во-вторых, keytoolне генерирует параметры самостоятельно для какого-либо алгоритма, только частная клавиша / пара ключей. В-третьих, когда keytoolгенерируется пара ключей, он также генерирует самоподписанный сертификат (который иногда впоследствии заменяется «настоящим» выданным СА сертификатом), и невозможно создать самоподписанный сертификат для DH, поскольку DH не подписывает. Вы можете написать очень простую (около 10 строк) Java-программу для генерации параметров DH. Но это, вероятно, не принесет вам пользы, потому что:

В любом случае Java здесь не принимает параметры DHE. JbossWS (веб-сервер Jboss, позже Wildfly) является форком Tomcat и обычно использует реализацию Java SSL / TLS, JSSE. До Java 7 JSSE использует свои собственные параметры DHE, которые являются 768-битными, что недопустимо слабо. (За исключением комплектов EXPORT, где JSSE подчиняется требованию RFC для DH-512, который полностью нарушен, но затем комплекты EXPORT по своему дизайну полностью нарушены и отключены по умолчанию в Java 7 и выше.) Java 8 JSSE позволяет вам контролировать размер параметров DHE, но не фактическое значение.

Ваши (некоторые перекрывающиеся) варианты:

Используйте Java 8. JSSE в Java 8, но не ранее, по умолчанию использует DHE равным 1024 битам, что большинство авторитетных организаций считает достаточно сильным, даже если и не слабый, и позволяет указать больше, см. Https://docs.oracle.com. /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys и для фона /programming/30352105/how-to-set-custom-dh-group-in-java -Slengine-to-предотвращать-logjam-атаку . Обратите внимание, что если у вас есть клиенты Java до Java 8, они потерпят неудачу, если сервер использует DHE более 1024 бит. Я не знаю других клиентов, у которых есть эта проблема, но проверьте своих, прежде чем совершать эти изменения.

Включить ECDHE. JSSE в Java 7 и более поздних версиях реализует ECDHE, который не подлежит предварительному вычислению, как DHE, (обычно) с использованием P-256, что более чем достаточно. (Хотя некоторые люди не доверяют ни одной из кривых NIST ECC, потому что NSA в целом влияет на NSA, хотя ни один из открытых источников, о которых я знаю, не обнаружил проблемы именно в кривых ECC.) В Java 6 фактически есть часть JSSE для ECDHE но он включается только в том случае, если JVM имеет крипто-провайдера для примитивов ECC, чего нет в Java 6. bcprov - * - jdk15on из http://www.bouncycastle.org/ является поставщиком JCE для ряда криптографических примитивов Java, включая ECC, поэтому, если вы добавляете jar в свой файл JRE/lib/extи добавляете org.bouncycastle.jce.provider.BouncyCastleProviderего в список JRE/lib/security/java.security(или делаете подходящееSecurity.add/insertProvider()где-то рано в вашем коде) Java 6 может сделать ECDHE. Конечно, стоит ли вам использовать Java 6 - это вопрос сам по себе.

Несколько лет назад поддержка ECDHE в браузерах и других клиентах была ненадежной, но сегодня AFAIK все современные браузеры поддерживают ее и предпочитают ее DHE - то есть браузер привет перечисляет комплекты ECDHE до того, как комплекты DHE так что если сервер реализует оба, он должен выбрать ECDHE. Не браузерные клиенты, возможно, нет; проверить, чтобы быть уверенным.

Отключить DHE. Вы можете настроить список шифров в атрибуте Connector, чтобы исключить DHE-шифры; при этом вы также исключаете staticDH и staticECDH, которые бесполезны, и (один) DES и (все) «EXPORT», если присутствует (Java 6). Это означает, что браузеры и клиенты, которые не используют ECHDE, будут зависеть от обычного RSA и без прямой секретности, но, по крайней мере, у них будет «текущая» секретность. Я не помню точно, но я думаю, что конфигурация 5.1 Connector была еще где-то как $server/deploy/jbossweb/server.xml.

Попробуй родной. Tomcat, с которого, как я уже сказал, начал JbossWS, имеет опцию для реализации HTTPS (SSL / TLS), используя «нативный» или «APR», который на самом деле является OpenSSL внутри, а не JSSE. Я имел неоднозначный успех в том, чтобы заставить эту опцию работать на JbossWS, и не вспоминаю о 5.1. Если ваш JbossWS имеет работоспособную TC-родной вариант, и если он может обрабатывать настройки параметров DH, а затем использовать OpenSSL для формирования параметров DH и инструкции JbossWS-нативной настроить их.

dave_thompson_085
источник
Спасибо за эту замечательную информацию. В конечном счете, ответ для нас не был связан с keytool, только с изменениями в нашем файле server.xml, но я собираюсь проверить этот ответ.
user2072931
4

На самом деле вы можете указать пользовательские параметры DHE в последних версиях Java 8 . Это не зависит от приложения (если оно использует реализацию JSSE TLS).

Сначала необходимо указать размер ключа DHE для использования ( -Djdk.tls.ephemeralDHKeySize=1024или -Djdk.tls.ephemeralDHKeySize=2048). На сервере это будет использовать заранее определенную комбинацию генератор / простое для DHE. С Java 8 можно использовать только 1024 или 2048, JDK 9 будет поддерживать большие размеры .

Если вы хотите предоставить другую комбинацию, вы можете указать их в jre / lib / security / Java.security со jdk.tls.server.defaultDHEParametersсвойством security (начиная с 8u51). Он принимает список параметров (по одному для каждого используемого размера ключа) и должен содержать простое число и генератор (обычно 2 или 5) в виде шестнадцатеричного числа.

Если вы использовали openssl dhparam -out dhparam2048.pem 2048для создания новой пары, вы можете использовать openssl dhparam -noout -text -check -in dhparam2048.pemдля чтения и печати этого файла в текстовом режиме. Вам придется скопировать и вставить текст в свойства безопасности Java (используя tr -d ':'для удаления :шестнадцатеричное представление openssl)

Вот пример (только 1024 бис):

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

И это приводит к

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

Вам следует перезапустить Сервер и убедиться, что он на самом деле использует это простое число (а не значения по умолчанию), поскольку процесс не является прямым Вперед, поэтому многое может пойти не так. Значение по умолчанию определено в источнике , для 2048-разрядного простого числа используется черновик TLS FFDHE.

Например, при запуске openssl s_client я вижу 1024-битное простое число ( ffffff ffffffffffc90f ... 5381ffffffffffffffff ) при подключении к серверу 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 ...

Вместо этого вы должны увидеть ваши пользовательские параметры при установке.

Параметры по умолчанию для Java 7 (768bit) будут "e9e642 ... 7a3daf" с длинным генератором "30470ad..529252", как определено в ParameterCache .

Экес
источник
3

Я проходил через ту же проблему, но из Glassfish.

Во-первых, я бы порекомендовал (если вы можете) установить своего рода обратный прокси-сервер перед вашим сервером JBoss, так как он удалит связь между безопасностью шифра / сертификата и версией Java, которую вы используете.

Чтобы получить большую длину ключа Ephemeral DH, чем 768 бит, вам нужно работать на Java 8. 1024 - это новое значение по умолчанию, и вы можете перейти к 2048, используя jdk.tls.ephemeralDHKeySize(подробности: настройка ключей DH ). Из того, что я мог найти, нет концепции регенерации ключевых параметров отдельно в Java.

Дэвид Хатчисон
источник
Спасибо за это предложение альтернативы. Мы можем рассмотреть это в будущем.
user2072931
Есть сейчас, см. Serverfault.com/a/798036/4591
eckes
для Glassfish / Payara / Payara-Micro отключить шифры DHE добавить <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>к <protocol name="http-listener-2" security-enabled="true">соединителю SSL
Маркус