有没有解决方法:java.lang.RuntimeException: Could not generate DH keypair

5

我正在测试一个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。我替换了以下两个文件:java.securityjava.policyC:\Program Files (x86)\Java\jre7\lib\security中。请注意,我还注意到我安装了Java\jre7\security在:Program Files (x86)Program Files,我都进行了替换。但是,我仍然看到相同的错误。
这个错误有什么解决方法吗? 编辑: 堆栈跟踪:
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

编辑2: 我的代码作为客户端试图与远程服务器(网站)进行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支持。如何配置Java客户端以支持在服务器提供长DH密钥时发起SSL握手?

你能展示完整的堆栈跟踪吗? - Henry
你读取了堆栈跟踪中的最后一个异常吗?你可能正在尝试在代码中某处设置质数大小吗?如果是这样,那么你很可能做错了。 - us2012
1
BouncyCastle被广泛使用,并且经过了充分的测试。如果它能解决你的问题,你不应该犹豫使用它。 - Henrik Aasted Sørensen
1
素数大小必须是64的倍数,且只能在512到1024之间(包括端点)。也许你在某个地方有一些偏差?错误信息似乎非常清楚。 - Dariusz
@Dariusz Wawer:我知道这个错误和原因,但我需要绕过它。似乎有可能的方法可以解决这个问题。但是,对我来说没有起作用。 - Wiliam A
1个回答

3
是的,基本上是#6851461的副本,还有#9162249和#10687200。无限强度策略不是解决方案。
在SSL/TLS客户端中,DHE(以及其他DH)的主要大小必须从服务器接收到的参数设置,并且必须设置,客户端无法选择其他内容。(这是堆栈跟踪中的ClientHandshaker.serverKeyExchange。)
您已经优先考虑使用ECDHE-RSA(在Java 7中正常工作,在6中如果添加了一个ECC提供程序,例如但不一定是BouncyCastle),而服务器没有选择它。您不提供明文RSA;如果您愿意放弃前向保密性,而服务器也愿意,可以尝试在_DHE_RSA之前(或替换为)添加一些套件,例如_RSA_WITH_AES_128_CBC_SHA _RSA_WITH_RC4_128_SHA。
另一个可能性是要求服务器操作员使用1024位DH,如果他们愿意并被允许。它实际上还没有被破解,但是它被一些重要标准禁止使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接