Java 获取无法生成DH密钥对异常

Java 获取无法生成DH密钥对异常,java,ssl,openssl,vcenter,Java,Ssl,Openssl,Vcenter,当vCenter(5.5)尝试从https服务器下载zip文件时,我遇到了这个异常。VCenter server具有JRE 1.6.0.31。我知道Java1.6和1.7中存在与同一问题相关的bug。此异常是由java.security.invalidalgorithParameterException引起的:素数大小必须是64的倍数,并且只能在512到1024(包括)之间 我可以从https服务器更改SSL证书。我试图通过使用OpenSSL生成新证书来解决这个问题(OpenSSL req-ne

当vCenter(5.5)尝试从https服务器下载zip文件时,我遇到了这个异常。VCenter server具有JRE 1.6.0.31。我知道Java1.6和1.7中存在与同一问题相关的bug。此异常是由
java.security.invalidalgorithParameterException引起的:素数大小必须是64的倍数,并且只能在512到1024(包括)之间

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

case K_DHE_DSS:
case K_DHE_RSA:
    this.serverKeyExchange(new DH_ServerKeyExchange(input, serverKey,
    clnt_random.random_bytes, svr_random.random_bytes,messageLen));
是否有任何方法可以生成SSL证书以避免执行此代码(可能是没有DH密钥对的SSL证书)


提前谢谢

密钥交换是DHE_RSA,这意味着Diffie Hellman通过RSA的短暂身份验证。DHE密钥,甚至DHE参数,不在证书中,它是长期的(FSVO long),而不是短暂的。证书中的密钥是RSA,Java在处理安全大小的RSA时没有问题,目前的安全大小超过1024,传统上是2048

  • 直接解决方法是使用旧的Java兼容的弱DH(E)参数。可能有十几个或更多的SSL/TLS服务器程序使用OpenSSL,或者使用PEM格式文件作为证书和(RSA)私钥。(很多软件使用PEM或可以为cert处理PEM,但大多数OpenSSL为privatekey处理PEM。)这些服务器程序中的许多都允许配置DH(E)参数,但我所看到的所有程序都是不同的,并且您无法识别您的

  • 一种解决方法是避免使用DHE_,并使用普通RSA密钥交换。包括OpenSSL在内的所有SSL/TLS实现都实现了这一点。然而,大多数应用程序和/或中间件不再喜欢它,有些甚至不允许它,因为它不提供。如何控制密码套件,从而控制密钥交换,同样取决于未识别的服务器程序

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

    3A。Java6JSSE实现ECDHE协议,但仅当JRE中有用于ECC原语的JCE“提供者”且交付的Oracle/Sun JRE6(以及TTBOMK-OpenJDK)没有ECC提供者时,才启用这些协议。要将ECC提供程序添加到JRE6中

    • 从下载
      bcprov-jdk15on-$version.jar
      并将其放入您的
      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)启用密码套件(默认情况下为true,但可能会被服务器程序或其配置禁用),以及(2)服务器程序设置tmp_ecdh参数(或在1.0.2中启用自动设置)。这两者都依赖于未识别的服务器程序,如果服务器程序不使用OpenSSL,答案可能会非常不同

  • 如果您识别您的服务器程序及其配置中与SSL/TLS相关的部分,我(或者其他人)可以更具体

    编辑服务器是nginx

    (1) nginx应该能够使用DHE-params-Java(6,7)来处理、查看和创建文件

     openssl dhparam 1024 >mydhfile
    
    (或者,如果您确实需要,可以使用更小的DSA-1大小=512到1024,以及64的倍数,但您不需要,我也不建议使用小于1024的大小)

    (2) 另外,要禁用DHE,请不要添加它,而是在ssl_密码字符串中至少添加一些kRSA(或仅添加RSA)。将注释中的字符串至少更改为

     EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH:kRSA:!RC4:!aNU‌​LL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS
    
    或者因为未经修改的JRE6不提供ECDHE(或TLSv1.2),我们也没有添加任何需要删除的PSK、SRP、DSS或aNULL,而且您不信任3DES(为什么?),RC4和Java也没有实现SEED或Camellia,所以您可以简单地使用它

     AES128-SHA:AES256-SHA 
    
    (这些实际上是TLS_RSA_和_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,并且openssl1.0.2可用,请使用
    openssl s_客户端-连接主机:端口-tls1-密码EDH+AES
    ;连接时输入Q,返回;查看大约20条“服务器临时密钥”线路。

    密钥交换是DHE_RSA,这意味着Diffie Hellman是通过RSA认证的临时密钥。DHE密钥,甚至DHE参数,不在证书中,它是长期的(FSVO long),而不是短暂的。证书中的密钥是RSA,Java在处理安全大小的RSA时没有问题,目前的安全大小超过1024,传统上是2048

  • 直接解决方法是使用旧的Java兼容的弱DH(E)参数。可能有十几个或更多的SSL/TLS服务器程序使用OpenSSL,或者使用PEM格式文件作为证书和(RSA)私钥。(有很多