DH ServerKeyExchange 不符合算法约束

DH ServerKeyExchange does not comply to algorithm constraints

我们最近升级了我们的一个工具(使用 java 实现),现在很难连接到我们公司的一个内部端点。对于其他端点,它工作正常。假设它不起作用的端点是 xyz.abc.com 我们每次看到的错误是

javax.net.ssl.SSLHandshakeException: DH ServerKeyExchange does not comply to algorithm constraints
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:258)
        at sun.security.ssl.DHServerKeyExchange$DHServerKeyExchangeConsumer.consume(DHServerKeyExchange.java:540)
        at sun.security.ssl.ServerKeyExchange$ServerKeyExchangeConsumer.consume(ServerKeyExchange.java:111)
        at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:377)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
        at sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:149)
        at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1143)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1054)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:394)
        at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:708)
        at sun.security.ssl.SSLSocketImpl.access0(SSLSocketImpl.java:72)
        at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:961)
        at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:933)
我遵循了以下建议:-

然而这似乎不起作用。

由于这个问题现在只在我们升级工具后才普遍存在,我们想知道这是否可能是由于强制执行了更新的 jvm 安全限制,是否有任何我们可以作为 jvm 参数传递或可能只是修改的东西java.security 文件或其他地方来解决这个恼人的问题 error.We 不想更改该端点使用的证书上的任何内容。 我是密码学的新手,因此如有任何帮助或建议,我们将一如既往地不胜感激。

我能够通过将 java 加密策略修改为 :-

来解决这个问题

jdk.tls.ephemeralDHKeySize=1024
jdk.certpath.disabledAlgorithms=MD2, MD5, DSA, RSA keySize < 2048
jdk.tls.disabledAlgorithms=DH keySize < 1024, SSLv2, SSLv3, TLSv1, TLSv1.1, DHE_DSS, RSA_EXPORT, DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, DH_anon, ECDH_anon, DH_RSA, DH_DSS, ECDH, 3DES_EDE_CBC, DES_CBC, RC4_40, RC4_128, DES40_CBC, RC2, HmacMD5
jdk.tls.legacyAlgorithms=

我不得不将 DHKeySize 的 2048 替换为 1024

分享给同样遇到同样问题却改不了的人。

很有可能

  • 您端点的证书正在使用 DH 密钥大小 1024。
  • 在java.security中,jdk.tls.disabledAlgorithms设置为禁用DH keySize < 2048

在这种情况下,包含“jdk.tls.disabledAlgorithms=DH keySize < 1024”的原始解决方案有效。

在Linux类似环境中,您可以验证用于签署主机证书的DH密钥大小。

openssl s_client -connect <host>:<port> -msg

你应该从上面的结果中找到这一行

Server Temp Key: DH, 1024 bits

对于那些发现仅更新 java.security 文件并不能解决问题的人来说,可能是有一个外部文件覆盖了某些设置。在 java.security 中查找以下设置。要么将此配置设置为 false,要么像原来那样更新外部文件 post。

security.overridePropertiesFile=true

虽然 Oracle 不鼓励使用较弱的加密算法,但您 whether/when 是否可以遵循。

Oracle JRE and JDK Cryptographic Roadmap

在 Red Hat Enterprise Linux 8.5 系统上,我通过像这样将系统设置为 LEGACY 模式解决了这个问题。更多信息在这里 https://access.redhat.com/articles/3666211

$ update-crypto-policies --show
DEFAULT

$ sudo update-crypto-policies --set LEGACY
Setting system policy to LEGACY
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.

$ sudo reboot

根据手册页crypto-policies(7),我们应该创建一个自定义子策略定义,它降低了 DH 密钥交换的最小位数 (min_dh_size) java-tls 范围为 1024。

所以我们必须将/etc/crypto-policies/policies/modules/LEGACY-DH-JAVA.pmod创建为

min_dh_size@java-tls = 1024

并更新了系统范围的策略

$ update-crypto-policies --show
DEFAULT

$ sudo update-crypto-policies --set DEFAULT:LEGACY-DH-JAVA
Setting system policy to DEFAULT:LEGACY-DH-JAVA
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.

注意:System-wide 加密策略应用于应用程序 start-up。

所以我们必须在这个更改后重新启动我们的 Java 应用程序。