2013-01-10 102 views
4

我正在测试Java应用程序。我正在尝试使用DH密码套件启动SSL握手。但我收到以下错误:是否有解决方法:java.lang.RuntimeException:无法生成DH密钥对

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。请注意,我也注意到我已经安装了Java\jre7\securityProgram 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 

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支持客户端列表中的所有密码套件。如何配置Java客户端以支持在服务器提供长DH密钥时启动SSL握手?

+0

你可以显示完整的堆栈跟踪吗? – Henry

+0

您是否读过堆栈跟踪中的最后一个异常?你可能试图在代码中的某个地方设置素数大小吗?如果是这样,你可能做错了。 – us2012

+1

BouncyCastle被广泛使用,并且经过很好的测试。如果它能解决您的问题,您应该毫不犹豫地使用它。 – Henrik

回答

3

是的,基本上也是#6851461的复制#9162249和#10687200。无限强度的政策不是解决方案。

SSL/TLS客户端中DHE(和其他DH)的主要大小是并且必须根据从服务器接收的参数进行设置,客户端无法选择不同的东西。 (这就是堆栈跟踪中的ClientHandshaker.serverKeyExchange)。

您已经拥有ECDHE-RSA(在Java 7中可以正常工作,或者如果添加ECC提供程序(例如但不一定是BouncyCastle),则优先于DHE-RSA,并且服务器没有选择它。你不提供普通的RSA;如果您愿意不使用正向保密并且服务器也在使用,则可以在_DHE_RSA之前(或代替)_DHE_RSA之前尝试至少添加一些套件,如_RSA_WITH_AES_128_CBC_SHA _RSA_WITH_RC4_128_SHA。

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

相关问题