获取无法生成DH密钥对例外

Bhu*_*han 0 java ssl openssl vcenter

当vCenter(5.5)尝试从https服务器下载zip文件时,我收到此异常.VCenter服务器具有JRE 1.6.0.31.我知道Java 1.6和1.7中与相同问题相关的bug.此异常是由 java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive).

我可以从https服务器更改SSL证书.我试图通过使用OpenSSL(openssl req -new -x509 -newkey rsa:1024 -days 365 -out server.crt -extensions usr_cert )和其他选项生成新证书来解决此问题.我查看了sun.security.ssl.ClientHandshaker代码,有一个switch case执行以下代码行并生成异常.

case K_DHE_DSS:
case K_DHE_RSA:
    this.serverKeyExchange(new DH_ServerKeyExchange(input, serverKey,
    clnt_random.random_bytes, svr_random.random_bytes,messageLen));
Run Code Online (Sandbox Code Playgroud)

有没有办法生成SSL证书,这将避免此代码执行(可能是没有DH密钥对的SSL证书)?

提前致谢!

dav*_*085 5

密钥交换是DHE_RSA,这意味着由RSA验证的Diffie Hellman Ephemeral.DHE密钥,甚至DHE参数都不在证书中,这是长期的(FSVO长)而不是短暂的.证书中的密钥是RSA,Java在安全大小处理RSA没有问题,现在大于1024,传统上是2048.

  1. 直接修复是使用旧的Java兼容的弱DH(E)参数.可能有十几个或更多SSL/TLS服务器程序使用OpenSSL,或者使用PEM格式文件作为证书(RSA)私钥.(许多软件使用或可以处理PEM用于证书,但主要是OpenSSL对私钥进行处理.)许多服务器程序允许配置DH(E)参数,但我见过的所有参数都不同,而且你不喜欢识别你的.

  2. 解决方法是避免DHE_anything并使用plain-RSA keyexchange.包括OpenSSL在内的所有SSL/TLS实现都实现了这一点.但是,大多数应用程序和/或中间件不再喜欢它,有些甚至不允许它,因为它不提供Forward Secrecy.如何控制密码套件,从而密钥交换,又取决于未识别的服务器程序.

  3. 更好的解决方法是启用ECDHE(特别是ECDHE_RSA,因为您的证书/密钥是RSA),如果可以的话.

    3A.Java6 JSSE实现了ECDHE协议,但只有在JRE中存在用于ECC原语的JCE"提供程序"时才启用它们 - 并且交付的Oracle/Sun JRE6(以及也是OpenJDK的TTBOMK)没有ECC提供程序.要ECC提供程序添加到JRE6

    • bcprov-jdk15on-$version.jarhttp://www.bouncycastle.org/latest_releases.html下载并将其放入您的JRE/lib/ext

    • 编辑JRE/lib/security/java.security以向提供者列表添加一行security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider,其中N是下一个可用数字.

    JRE7确实包含ECC提供程序,并支持开箱即用的ECDHE,如果这是一个选项.

    3B.如果您的服务器使用OpenSSL 1.0.0或更高版本(某些较旧的RedHat版本除外)它实现了ECDHE,但只有在(1)密码套件启用时才能使用它,默认情况下这是真的,但可以被服务器程序禁用或其配置,以及(2)服务器程序设置tmp_ecdh参数(或在1.0.2中启用自动设置).这两个都取决于未识别的服务器程序,如果服务器程序不使用OpenSSL,答案可能会有很大不同.

如果您确定了您的服务器程序以及其配置中与SSL/TLS相关的部分,我(或可能是其他人)可能更具体.

编辑服务器是nginx:

(1)nginx应该能够使用DHE params Java(6,7)可以处理,参见http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam并创建文件

 openssl dhparam 1024 >mydhfile
Run Code Online (Sandbox Code Playgroud)

(或者,如果你真的想要,一个较小的DSA-1大小= 512到1024和64的倍数,但你不需要,我不建议小于1024).

(2)alernatively,禁用DHE,添加它,但不要在的ssl_ciphers字符串添加至少一些kRSA(或只是RSA).将评论中的字符串至少更改为

 EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH:kRSA:!RC4:!aNU??LL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS
Run Code Online (Sandbox Code Playgroud)

或者因为未经修改的JRE6不会提供ECDHE(或TLSv1.2)而且我们没有添加任何需要删除的PSK或SRP或DSS或aNULL,并且您不信任3DES(为什么?)而RC4和Java没有实施SEED或Camellia,您可以更简单地使用它

 AES128-SHA:AES256-SHA 
Run Code Online (Sandbox Code Playgroud)

(这些实际上是TLS_RSA_WITH_AES*_CBC_SHA,但对于歇斯底里的葡萄干,OpenSSL名称省略了RSA和CBC.)

Tomcat默认使用Java(JSSE)来处理HTTPS连接,但是根据打包/安装,通常可以使用APR,也称为"Tomcat native"或者只是"native",实际上是OpenSSL.如果Tomcat/JSSE在JRE6或7上运行,它使用JRE6,7客户端可以处理的DHE大小768; 如果在JRE8上运行,则默认大小为1024,JRE6,7客户端可以处理.我不知道Tomcat/APR使用什么(并且不能轻易测试),但它可能是1024或更少.如果你想找到并运行Tomcat/APR和openssl 1.0.2,请使用openssl s_client -connect host:port -tls1 -cipher EDH+AES; 连接时输入Q,返回; 查看"服务器临时密钥"大约20行.