我正在尝试重现在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加密扩展(JCE)无限强度权限策略文件“(但正如在另一篇文章中提到的,这对他们不起作用)。
为了重现这个问题,我尝试在具有类似环境(也使用Axis2)的单独部署中托管一个web服务。这有一个创建和配置SSLServerSocket的自定义SSLServerSocketFactory。
使用Wireshark (还有javax.net.debug JVM参数),我可以看到协商的密码套件是TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,但ServerKeyExchange中的Prime DH Server Param只有96字节(768位)。
有没有什么方法可以将SSLServerSocket配置为在握手期间使用更大的素数?
我猜密钥是由RSA的安全提供商从JRE生成的。我是否需要添加自己的提供程序并将其添加到jre/lib/security/java.security?
如果这是一个愚蠢的问题,我对DHE an Cipher Suites还是个新手。我只需要了解足够的知识就可以让服务器测试正常工作(我不涉及客户端实现)。
发布于 2015-04-08 08:59:42
因此,在EJP的正确方向上,我最终设法准确地追踪到强度(以及随后的DH参数)被确定的位置。它确实在JRE中(特别是在ServerHandshaker中)。
使用具有强度限制(如原始帖子中提到的)的较旧JRE的安全提供程序在这里将不起作用。虽然使用其他安全提供程序可能会防止此错误,但客户端的强度在初始化KeyPairGenerator实现之前就已经确定了。
顺便说一句,我没有费心升级JRE来重现这一点。我只是添加了带有调试信息的BouncyCastle JCE提供程序,在org.bouncycastle.jcajce.provider.asymmetric.dh.KeyPairGeneratorSpi.initialize(int,( SecureRandom)方法中设置了一个断点,并手动更改了强度。这对我的测试来说已经足够好了。
https://stackoverflow.com/questions/29483924
复制相似问题