【问题标题】:Is there a workaround for: java.lang.RuntimeException: Could not generate DH keypair [duplicate]是否有解决方法:java.lang.RuntimeException:无法生成 DH 密钥对 [重复]
【发布时间】:2012-12-24 13:15:07
【问题描述】:

我正在测试一个 Java 应用程序。我正在尝试使用 DH 密码套件启动 SSL 握手。但我收到以下错误:

java.lang.RuntimeException: Could not generate DH keypair

有人建议BouncyCastle,但是很多人都报错了,所以如果有其他选择,我不鼓励使用它。

有人建议从http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。我确实在C:\Program Files (x86)\Java\jre7\lib\security 中替换了以下两个文件java.securityjava.policy。请注意,我还注意到我在Program Files (x86)Program Files 中安装了Java\jre7\security,并且我替换了两者。但是,我仍然看到同样的错误。

这个错误有什么解决方法吗?

编辑: 堆栈跟踪:

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at MyClass.MyClass.myFunction(MyProg.java:78)
    at MyClass.MyClass.main(MyClass.java:233)
Caused by: java.lang.RuntimeException: Could not generate DH keypair
    at sun.security.ssl.DHCrypt.<init>(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverKeyExchange(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    ... 4 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(Unknown Source)
    ... 11 more

EDIT2: 我的代码充当客户端,尝试与远程服务器(网站)启动 SSL 握手。我将客户端的密码套件列表设置为:

{
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_NULL_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",  
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"
};

Java 支持客户端列表中的所有密码套件。当服务器提供长 DH 密钥时,如何配置 Java 客户端以支持发起 SSL 握手?

【问题讨论】:

  • 你能显示完整的堆栈跟踪吗?
  • 您是否阅读了堆栈跟踪中的最后一个异常?您是否可能尝试在代码中的某处设置素数大小?如果是这样,你可能做错了。
  • BouncyCastle 被广泛使用,并且经过很好的测试。如果它可以解决您的问题,您应该毫不犹豫地使用它。
  • “素数大小必须是 64 的倍数,并且只能在 512 到 1024(含)之间” - 也许你在某个地方不合时宜?错误信息似乎很清楚
  • @Dariusz Wawer:我知道错误和原因,但我需要解决这个问题。似乎有可能的方法来做到这一点。但是,没有和我一起工作。

标签: java sockets ssl network-programming


【解决方案1】:

是的,基本上是 #6851461 以及 #9162249 和 #10687200 的欺骗。无限强度政策不是解决方案。

SSL/TLS 客户端中 DHE(和其他 DH)的素数大小是并且必须根据从服务器接收到的参数设置,客户端不能选择不同的值。 (即堆栈跟踪中的 ClientHandshaker.serverKeyExchange。)

您已经拥有优先于 DHE-RSA 的 ECDHE-RSA(在 Java 7 或 6 中运行良好,如果您添加了 ECC 提供程序,例如但不一定是 BouncyCastle),但服务器没有选择它。您不提供纯 RSA;如果您愿意不使用前向保密并且服务器也是,请尝试在 _DHE_RSA 之前(或代替)添加至少一些套件,例如 _RSA_WITH_AES_128_CBC_SHA _RSA_WITH_RC4_128_SHA。

另一种可能性是要求服务器运营商使用 DH 1024 位,如果他们愿意并允许的话。它实际上还没有被破坏,但它被一些重要的标准所禁止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2014-06-26
    • 2015-08-25
    • 2011-01-28
    • 2011-10-14
    相关资源
    最近更新 更多