当前位置: 首页 > 知识库问答 >
问题:

Java 7和无法生成DH密钥对

颜楚青
2023-03-14

我以前读过一篇文章,内容是关于服务器发送超过1024位的密钥时引发的错误“无法生成DH密钥对”。下载JCE无限jar应该可以解决这个问题。在测试环境中,我遇到了以下情况,对于同一个web服务器,如果我使用Java 6,则在执行https查询时不会出现任何错误,但如果我使用Java7,则会出现“无法生成DH密钥对”。

我尝试替换JCE无限的jar文件,但仍然得到同样的错误。该错误自2007年以来一直被报告,但为什么它适用于Java 6而不是Java 7?要下载的文件不是正确的文件吗?我从上一篇文章Java中获得了链接:为什么SSL握手给出“无法生成DH密钥对”异常

此时我不知道该怎么办。如果我尝试加载BouncyCastle提供程序,我会得到一个ArrayOutOfIndex异常。我的服务器只允许DH算法,所以我不能使用其他算法,就像上面的帖子中建议的那样。

共有3个答案

薛祯
2023-03-14

如果您使用的是最新的java版本,但仍然出现错误,您可以在java.security中更改设置(例如,在文件夹C:\ Program Files \ Java \ JRE 1 . 8 . 0 _ xx \ lib \ security中)

# Example:
#   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
    jdk.tls.disabledAlgorithms=SSLv3, RC4

在 jdk.tls.disabledAlgorithms 中添加 DH 作为禁用算法

    jdk.tls.disabledAlgorithms=SSLv3, RC4, DH

重新启动tomcat或重新运行程序。

郭单鹗
2023-03-14

我在SSLScokets中偶然发现了同样的问题,我想我在Java 7中找到了这种回归的原因。原因在于客户机和服务器之间协商的密码。

默认情况下Java6为TLS连接启用这些密码(按优先级顺序):

SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
SSL_RSA_EXPORT_WITH_RC4_40_MD5
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV

Java 7支持这些密码:

TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_RC4_128_SHA
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_RC4_128_SHA
TLS_ECDH_ECDSA_WITH_RC4_128_SHA
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_RC4_128_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_RC4_128_MD5
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA

使用Diffie-Hellman的密码在Java7上具有更高的优先级,但它们似乎不支持超过1024位的密钥,除非安装了强大的加密包。

我使用的解决方法是在SSLSocket上指定Java6启用的密码:

SSLSocketFactory socketFactory = SSLContext.getInstance("TLS").getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(InetAddress.getByName(hostname), port);
socket.setEnabledCipherSuites(new String[] {
        "SSL_RSA_WITH_RC4_128_MD5",
        "SSL_RSA_WITH_RC4_128_SHA",
        "TLS_RSA_WITH_AES_128_CBC_SHA",
        "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
        "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
        "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
        "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
        "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
        "SSL_RSA_WITH_DES_CBC_SHA",
        "SSL_DHE_RSA_WITH_DES_CBC_SHA",
        "SSL_DHE_DSS_WITH_DES_CBC_SHA",
        "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
        "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
        "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
        "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
        "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"});

socket.startHandshake();
年文柏
2023-03-14

一些补充或澄清:

(太阳)Java 7 自 7u09 以来,默认情况下使用更合理的一致密码套件顺序,这与 7u04 中看似随机的顺序不同。(我没有 04 到 09 之间的测试。此顺序将 ECDHE 和普通 RSA(又名 akRSA)放在 DHE 之前,因此当且仅当服务器支持 ECDHE 或 RSA 并同意客户端首选项时,才能避免此问题。(或ECDH固定,但实际上没有人使用它。如果服务器坚持使用 DHE(无论出于何种原因)并使用 DH

如果询问者(或其他任何人)连接到真正需要整数DH(而不是ECDH或RSA)的服务器,使用8之前的Java的唯一方法是让服务器使用DH 1024位。AFAWK在技术上还能再安全几年,但像NIST这样的重要机构禁止使用DH 1024位(参见csrc.nist.gov的特别酒吧800-57)。(即使RSA 1024实际上还没有损坏,但可能很快就会坏,所以是被禁止的。)

“无限强度政策”与这个问题无关,或者至少不直接相关,对#6851461的良好答案也没有说它是。它不会改变 SunJCE 中对 DH 参数的限制,这(错误地)被视为标准问题,而不是强度问题。(具体来说,它采用过去对DSA正确的限制,并将其应用于DH。它确实启用了 AES-256 和 SHA-2(仅适用于 TLSv1.2)套件,并且给定一个足够奇怪的首选项列表,这可能会将选择结果从 DHE(失败)更改为非 DHE(工作)。

您不需要完全返回Java6列表,只需要将其他密钥交换优先于DHE,或者对于顽固的服务器完全放弃DHE。您绝对不应该重新启用任何EXPORT或单个DES套件,除非遗留服务器绝对需要;他们已经几年不安全了,并且在6年内默认启用的时间比他们应该启用的时间长得多。

 类似资料:
  • 问题内容: 当我与某些IRC服务器(而非其他IRC服务器)建立SSL连接时(大概是由于服务器的首选加密方法),出现以下异常: 最终原因: 演示此问题的服务器示例是(这是一个IRC服务器)。未显示问题的服务器的示例是。[不足为奇的是,每个网络上的所有服务器都共享相同的行为。] 我的代码(如所述,在连接到某些SSL服务器时有效)是: 是最后一个startHandshake引发异常。是的,’trustA

  • 问题内容: 我目前正在将Reddit OAuth2登录实现到我的Web应用程序中。在本地进行测试时,握手和令牌交换工作正常,但是在服务器上运行(托管在“ OpenShift” DIY卡式盒上)时,出现以下错误: 这是结果 我一天中大部分时间都在搜索,发现了从更改Java版本到使用BouncyCastle的各种解决方案。但是,我使用的是Scribe库,所以我认为如果不分叉和更改抄写员的基础,就无法实

  • 我试图为某些设备生成密钥时出错。我能够在运行4.4.2的三星Galaxy Note上重现错误。 我创建了一个小应用程序,只能通过从Android开发者页面“生成新私钥”下的https://developer.android.com/training/articles/keystore.html逐行复制代码来生成密钥 错误似乎发生在kpg.generateKeyPair(),在Android Key

  • 我正在尝试创建一个公钥以允许我推送到Git,但我的. ssh文件夹尚未创建。 以下是我运行的命令: $ssh-keygen-t rsa-Cemaill@me.com 生成公共/私有rsa密钥对 输入保存密钥的文件(/h/.ssh/id\u rsa): 这就是H:驱动器配置、数据、配置文件、配置文件中的全部内容。V2 我认为有一个问题,因为当我得到提示输入文件,其中保存密钥(/h//. ssh/id

  • 使用Python-GnuPG我想 null 不幸的是,加密返回错误: 但它仍然生成加密ASCII铠甲消息,如果解密结果为对象,则bool值为属性,并包含以下属性: 不确定错误发生的确切位置以及如何处理

  • 我正在尝试用Java编写一个简单的密码管理器。我想用AES 256位加密用存储的密码加密文件。此外,我希望用户能够解密的文件与密码。当阅读其他在线帖子时,他们几乎都强调简单地使用密码作为密钥是不安全的,他们提到使用随机盐来增加安全性。但我不明白如何在生成密钥时使用随机盐。如果我从用户的密码和随机的salt创建密钥,那么当他们试图解密他们的文件时,我怎么知道salt是什么呢?这让我完全糊涂了。 目前