【问题标题】:Is there any way to specify the range for the Diffie-Hellman prime using javax.net.ssl.SSLServerSocket?有没有办法使用 javax.net.ssl.SSLServerSocket 指定 Diffie-Hellman 素数的范围?
【发布时间】:2015-04-07 04:44:51
【问题描述】:

我正在尝试重现 Java: Why does SSL handshake give 'Could not generate DH keypair' exception? 中提出的问题。

我有一个显示异常的日志:

Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1844)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1827)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1753)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:127)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:94)
    ... 27 more
Caused by: java.lang.RuntimeException: Could not generate DH keypair
    at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:136)
    at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:621)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:205)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
    ... 30 more
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658)
    at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:127)
    ... 38 more

我正在使用 Axis2 来调用 Web 服务。我在 jre/lib/security 中也有“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”(但正如在另一篇文章中提到的那样,这对他们不起作用)。

为了重现此问题,我尝试在具有类似环境的单独部署中托管 Web 服务(也使用 Axis2)。这有一个自定义 SSLServerSocketFactory,它正在创建和配置 SSLServerSocket。

使用 Wireshark(以及 javax.net.debug JVM 参数)我可以看到协商的密码套件是 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 但 ServerKeyExchange 中的 Prime DH 服务器参数只有 96 个字节(768 位)。

有什么方法可以配置 SSLServerSocket 在握手期间使用更大的素数?

我猜密钥是由 JRE 的 RSA 安全提供程序生成的。我是否需要添加自己的提供程序并将其添加到 jre/lib/security/java.security?

抱歉,如果这是一个愚蠢的问题,我通常是 DHE 和密码套件的新手。我只需要知道足够多的知识就可以让服务器测试正常工作(我没有涉及客户端实现)。

【问题讨论】:

  • 副本说它是四年前修复的。因此,解决方案是升级您的 Java 版本。
  • 我的问题完全不同。我正在尝试实现一个使用大于 1024 位的素数来生成 DHE RSA 密钥的服务器。
  • 我试图产生这种情况而不是解决它。正如我所说,我是这种事情的新手,所以如果是提供者(而不是策略)对客户端和服务器造成了相同的限制,那么请将其添加为答案。即使我要使用不同的提供程序,这是否会自动大于 1024 位,还是我需要配置它?
  • 它是提供限制的 Java 版本,正如它在重复的问题中所说的那样。如果您想重现它,请使用适当的版本。
  • 我感到困惑的是,它还说您可以使用 BouncyCastle 的 JCE 实现,表明它可能是安全提供者。

标签: java ssl rsa diffie-hellman public-key-exchange


【解决方案1】:

因此,随着 EJP 朝着正确的方向推进,我最终设法准确地找到了确定强度(以及随后的 DH 参数)的位置。它确实在 JRE 中(特别是在 ServerHandshaker 中)。

使用具有强度限制的旧 JRE 的安全提供程序(如原始帖子中所述)在此处不起作用。虽然使用其他安全提供程序可能会阻止此错误客户端,但在初始化 KeyPairGenerator 的实现之前已经确定了强度。

作为旁注,我没有费心升级 JRE 来重现这一点。我刚刚添加了带有调试信息的 BouncyCastle JCE 提供程序,在 org.bouncycastle.jcajce.provider.asymmetric.dh.KeyPairGeneratorSpi.initialize(int, SecureRandom) 方法中放置了一个断点并手动更改了强度。这对我的测试来说已经足够了。

【讨论】:

    猜你喜欢
    • 2020-09-12
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    相关资源
    最近更新 更多