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

use*_*931 11 security ssl java keys keytool

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

dav*_*085 13

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

无论如何,Java 在这里不接受 DHE 参数。JbossWS(Jboss webserver,后来的Wildfly)是Tomcat的一个分支,通常使用SSL/TLS、JSSE的Java实现。在 Java 7 之前,JSSE 使用它自己的 DHE 参数,这些参数是 768 位的,这是不可接受的。(除了 EXPORT 套件,其中 JSSE 遵守 DH-512 的 RFC 要求,该要求完全被破坏,但无论如何 EXPORT 套件在设计上完全被破坏,并且在 Java 7 中默认禁用。)Java 8 JSSE 允许您控制DHE 参数的大小,而不是实际值。

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

使用 Java 8。Java 8 中的JSSE,但不是更早,默认 DHE 为 1024 位,即使weakdh.org 没有,但大多数权威认为它足够强大,并允许您指定更多,请参阅https://docs.oracle.com /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys和背景/sf/ask/2124647381/ -sslengine-to-prevent-logjam-attack。请注意,如果您有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是一系列 Java 加密原语(包括 ECC)的 JCE 提供者,因此如果您将 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更喜欢它——也就是说,浏览器 hello 在 DHE 套件之前列出了 ECDHE 套件,所以如果服务器实现两者,则应选择 ECDHE。非浏览器客户端可能不会;测试确定。

禁用 DHE。您可以在 Connector 属性中配置密码列表以排除 DHE 密码;当您使用它时,还排除了无用的 staticDH 和 staticECDH,以及(单个)DES 和(所有)“EXPORT”(如果存在)(Java 6)。这意味着不执行 ECHDE 的浏览器和客户端将使用普通 RSA 并且没有前向保密,但至少它们具有“当前”保密性。我不太记得了,但我认为 5.1 连接器配置仍然像$server/deploy/jbossweb/server.xml.

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


eck*_*kes 5

实际上,您可以使用最新的 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 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.
Run Code Online (Sandbox Code Playgroud)

这导致

jdk.tls.server.defaultDHEParameters= \
    { \
        00f7a63b59edcc43a43df12077f0e9 \
        14129c20a73cef95f919896e608ebc \
        8722776c948765bbbf61542e118329 \
        6c6ea74ecbded3a93aff77a062aba4 \
        fcf04fc01030e65077f5a802605058 \
        65b836368dd5ea389d77691fac0f2c \
        f7a161c51c8e97ddecb3cf7f872b0c \
        cfaf54373d5203edcabc575e871bb1 \
        107ec2f30c78ebf403, 2 }
Run Code Online (Sandbox Code Playgroud)

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

例如,在运行 openssl s_client 时,我可以在连接到 Java 8 JSSE 服务器时看到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 ...
Run Code Online (Sandbox Code Playgroud)

取而代之的是,您必须在安装时看到您的自定义参数。

Java 7(768 位)的默认参数将是“e9e642...7a3daf”,带有一个在 ParameterCache 中定义的长生成器“30470ad..529252” 。