如何使用Java keytool生成新的2048位Diffie-Hellman参数?


9

我们到目前为止还没有成功,但我们仍然是非专家,我们尝试更新Web服务器(JBoss-5.1.0.GA)设置以满足Diffie-Hellman标准。在https://weakdh.org/sysadmin.html上运行测试之后,我们被告知需要“生成新的2048位Diffie-Hellman参数”。过去,我们是使用Java keytool生成密钥的,但是我们找不到有关使用Java keytool生成新的2048位Diffie-Hellman参数的信息。有谁知道该怎么做,或者可以为我们指明正确的方向?谢谢!

Answers:


13

您不能使用keytool做到这一点。首先,keytool根本不支持DH。其次,keytool不会针对任何算法自行生成参数,而只会生成私钥/密钥对。第三,当keytool生成密钥对时,它还会生成一个自签名证书(有时有时会被“真实的” CA颁发的证书代替),并且由于DH不签名,因此无法为DH生成自签名证书。您可以编写一个非常简单的Java程序(约10行)来生成DH参数。但这可能对您没有任何好处,因为:

Java此处始终不接受DHE参数。JbossWS(Jboss网络服务器,后来的Wildfly)是Tomcat的一个分支,通常使用SSL / TLS,JSSE的Java实现。直到Java 7为止,JSSE都使用自己的768位DHE参数,该参数太弱了。(除了JSSE完全遵循DH-512的RFC要求的EXPORT套件外,它完全被破坏了,但是EXPORT套件在设计上还是被完全破坏了,并且在Java 7 up中默认为禁用。)Java 8 JSSE允许您控制DHE参数的大小,但不能控制实际值。

您的(有些重叠)选项是:

在Java 8中使用Java 8(但不是更早版本)中的JSSE,将DHE缺省为1024位,即使weakdh.org不支持,大多数权威人士都认为DHE足够强,并且允许您指定更多位,请参见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 -sslengine防止logjam攻击。请注意,如果Java 8之前的Java 客户端,则如果服务器使用超过1024位的DHE ,它们将失败。我不知道有其他客户遇到此问题,但是请在进行此更改之前先对您的客户进行测试。

启用ECDHE。Java 7和更高版本中的JSSE实现了ECDHE,它不需要像DHE那样进行预计算(通常)使用P-256,它已经足够强大了。(尽管有些人不信任任何 NIST ECC曲线,因为NIST通常受NSA的影响,尽管据我所知,没有开源特别在ECC曲线中显示出问题。)Java 6实际上具有ECDHE的JSSE部分。但是只有在JVM具有ECC原语的加密“提供程序”的情况下才启用,而Java 6没有。来自http://www.bouncycastle.org/的 bcprov-*-jdk15on 是JCE提供程序,用于包括ECC在内的一系列Java加密原语,因此,如果将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 更喜欢它-也就是说,浏览器问候列表列出了DCD套件之前的ECDHE套件,因此如果服务器同时实现这两者,则应选择ECDHE。非浏览器客户可能不会;测试确定。

禁用DHE。您可以在Connector属性中配置密码列表,以排除DHE密码。当您使用它时,还应排除无用的staticDH和staticECDH,以及(单个)DES和(全部)“ EXPORT”(如果存在)(Java 6)。这意味着不执行ECHDE的浏览器和客户端将受制于纯RSA和无转发保密性,但是至少它们具有“当前”保密性。我不确定是否记得,但是我认为5.1 Connector config仍然像$server/deploy/jbossweb/server.xml

尝试本地。就像我说过的JbossWS一样,Tomcat可以选择使用“本机”或“ APR”来实现HTTPS(SSL / TLS),后者实际上是内部的OpenSSL,而不是JSSE。在使该选项在JbossWS上运行方面,我取得了不同的成功,并且不记得5.1了。如果您将JBossWS有一个可行的TC-本地选项,如果它能够处理配置DH参数,然后使用OpenSSL生成的DH参数和将JBossWS本地指令对它们进行配置。


谢谢您提供的重要信息。最终,我们的答案不涉及keytool,而只是更改了我们的server.xml文件,但我将检查该答案。
user2072931 2015年

4

实际上,您可以使用最新的Java 8版本指定自定义DHE参数。那就是应用程序的独立性(只要它使用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.defaultDHEParameterssecurity属性(从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 }

您应该重新启动服务器,并验证它是否实际上使用了该主服务器(而不是默认主服务器),因为该过程不直接进行,因此可能会出错。默认值在source中定义,对于2048位,素数来自TLS FFDHE草案。

例如,当运行openssl s_client 时,连接到Java 8 JSSE Server时可以看到1024位素数(ffffff ffffffffffc90f ... 5381ffffffffffffffff):

>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(768位)的默认参数为“ e9e642 ... 7a3daf”,带有ParameterCache中定义的长生成器“ 30470ad..529252” 。


3

我一直在经历同样的问题,但来自Glassfish。

首先,我建议(如果可以的话)在JBoss服务器前放置某种反向代理,因为它会删除密码/证书安全性与正在运行的Java版本之间的链接。

要获得大于768位的临时DH密钥长度,您需要在Java 8上运行。1024是新的默认值,您可以使用jdk.tls.ephemeralDHKeySize(详细信息: 自定义DH密钥)将其提高到2048 。据我所知,没有在Java中分别重新生成关键参数的概念。


感谢您提出的替代建议。我们将来可能会对此进行研究。
user2072931 2015年

现在有,请参阅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连接器
Markus,2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.