是否有解决方法:java.lang.RuntimeException:无法生成DH密钥对

我正在测试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 。 请注意,我还注意到我安装了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.(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握手?

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

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

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

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