证书异常:证书不符合算法约束条件。

37

我有一个地图应用程序,可以添加ArcGIS 9.3+基础地图,只需提供URL即可。其中一个我想添加的URL来自客户的地址,并且是安全的。我的映射应用程序之前使用的是Java 6,可以毫无问题地添加安全URL。我现在升级到Java 7,但遇到了

的问题。

"java.security.cert.CertificateException: Certificates does not conform to algorithm constraints"

异常。起初,我认为这是因为在Java 7中,默认情况下禁用了MD2算法来签名SSL证书。您可以在java.security文件中看到这一点:

"jdk.certpath.disabledAlgorithms=MD2"

但是当我检查该网址的认证签名算法时,它说SHA-1。更奇怪的是,如果我在java.security文件中注释掉"jdk.certpath.disabledAlgorithms=MD2"这一行,该URL将可以正常工作。在SSL过程中是否还使用了MD2?我错过了什么吗?


4
在使用512位RSA密钥时,我遇到了这个异常。我的java.security文件中有jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024的设置。我正在使用OpenJDK 7。 - Daniel
11个回答

54

背景

MD2被广泛认为是不安全的,并在Java JDK 6u17版本及更高版本中禁用(请参见发布说明http://www.oracle.com/technetwork/java/javase/6u17-141447.html, “禁用证书链验证中的MD2”),以及根据您在java.security中指定的配置,在JDK 7中也被禁用。

Verisign曾使用具有md2WithRSAEncryption签名算法(序列号为70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf)的Class 3根证书,但已将其弃用并用相同的密钥和名称替换为另一个证书,并使用sha1WithRSAEncryption算法进行签名。然而,仍有一些服务器在SSL握手期间发送旧的MD2签名证书(讽刺的是,我曾在由Verisign运行的服务器上遇到过此问题!)。

您可以通过从服务器获取证书链并检查它来验证这种情况:

openssl s_client -showcerts -connect <server>:<port>

近期版本的JDK(例如6u21和所有已发布的7版本)应该会通过自动删除与受信任锚点(默认情况下为cacerts)具有相同颁发者和公钥的证书来解决此问题。

如果您在更新的JDK中仍然遇到此问题

检查您是否有自定义信任管理器实现旧的 X509TrustManager 接口。 JDK 7+ 应该与此接口兼容,但根据我的调查,当信任管理器实现 X509TrustManager 而不是更新的 X509ExtendedTrustManager文档)时,JDK 使用其自己的包装器 (AbstractTrustManagerWrapper) 并绕过了此问题的内部修复。

解决方案是:

  1. 使用默认的信任管理器, 或者

  2. 修改您的自定义信任管理器以直接扩展 X509ExtendedTrustManager (一个简单的更改)。


你能否看一下我的(非常相似的)问题 - itsadok
7
openssl s_client命令不仅非常有用,而且解决我长达6小时的痛苦的方法是改变X509ExtendedTrustManager。 - user2591854
6
更改为“X509ExtendedTrustManager 是迄今为止最好的解决方案。非常感谢。” - Gianluca Greco

28

Eclipse无法连接到SVN https存储库(同样适用于使用SSL/TLS的任何应用程序)。

svn:E175002:连接已关闭:javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:证书不符合算法约束

该问题是由最新的Java 8 OpenJDK更新引起的,禁用了与MD5相关的算法。作为解决方法,在新证书颁发之前(如果有的话),请更改java.security文件中的以下密钥:

  

警告
  请记住,这可能会产生安全影响,因为禁用的算法被认为是弱的。   作为替代方案,可以通过使用命令行选项在JVM上应用此更改的workaround,例如:
  java -Djava.security.properties=/etc/sysconfig/noMD5.java.security
  对于Eclipse,请在eclipse.ini下添加一行:
  -Djava.security.properties=/etc/sysconfig/noMD5.java.security

原始密钥

jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768

改为

jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768

java.security 文件位于 Linux 64 上的 /usr/lib64/jvm/java/jre/lib/security/java.security


有没有代码的方法来覆盖Apache 4.4中的相同内容? - Vish
不确定,但似乎与SSLCipherSuite指令有关。在这里查看https://httpd.apache.org/docs/current/mod/mod_ssl.html。查找此字符串:RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5 - LMC
更改对我不起作用,我不得不注释掉这两行。 - sify

16
在Fedora 28中,请注意位于java.security文件中的以下行:

security.useSystemPropertiesFile=true

该文件可以在以下路径找到:

$(dirname $(readlink -f $(which java)))/../lib/security/java.security

Fedora 28引入了禁用算法的外部文件,位于以下路径:

/etc/crypto-policies/back-ends/java.config

您可以编辑此外部文件,或通过设置以下内容将其从java.security中排除:

security.useSystemPropertiesFile=false


1
我在使用Dbeaver和MS SQL JDBC 6.0 - 6.4时遇到了问题。这个解决方案对我有用,而设置-Djdk.tls.client.protocols=TLSv1则没有用。 - ElectronicBlacksmith
我在 Fedora 28 上遇到了证书 RSA 密钥小于 1024 被拒绝的问题 - 我从 /etc/crypto-policies/back-ends/java.config 中删除了该异常,现在一切正常。谢谢。 - paulmdavies
谢谢,这在 Fedora 30 上为我解决了问题。 - Janne
我在Centos 8和RHEL 8上遇到了这个问题,现在它们也有加密策略。 - Onnonymous

4

我们遇到了一个数据库问题,这个数据库不在我们的控制范围内,需要另一种解决方案(这里列出的解决方案都无法解决)。而对于我的情况,我需要:

-Djdk.tls.client.protocols="TLSv1,TLSv1.1"

我认为在我的情况下,这与强制执行某种顺序有关。


这是唯一一个帮助我解决DavMail中的“证书不符合算法约束”异常的解决方案。必须修改/usr/bin/davmail脚本以添加该选项。 - Alexander Amelkin

2

由于这个错误是谷歌返回的第一个结果,我想补充一下:如果有人想要更改 Java 安全设置而不更改全局文件 java.security(例如您需要运行一些测试),可以通过 JVM 参数-Djava.security.properties=your/file/path 提供一个覆盖安全文件,在其中通过覆盖禁用项启用必要的算法。


1
在 Red Hat EL8 上,运行 OpenJDK8。将以下属性的值从 true 更改为 false。
security.useSystemPropertiesFile = false

java.security文件中,我解决了上述问题。

1

同事们。

在开发自动化测试我们的REST API时,我遇到了这个问题。我的机器上只安装了JDK 7_80。在安装JDK 8之前,一切都正常,我可以使用JMeter获得OAuth 2.0令牌。但是在安装JDK 8之后,出现了“证书不符合算法约束”的噩梦。

无论是JMeter还是Serenity都无法获取令牌。JMeter使用JDK库来发出请求。当库调用连接到使用它的端点时,该库会引发异常,忽略请求。

接下来要做的是在所有java.security文件中注释所有禁用算法的行。

C:\Java\jre7\lib\security\java.security
C:\Java\jre8\lib\security\java.security
C:\Java\jdk8\jre\lib\security\java.security
C:\Java\jdk7\jre\lib\security\java.security

最终它开始工作了。我知道这是一种暴力的方法,但这是修复它最简单的方式。

# jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024

有一个比这个临时解决方案更好的解决方案 :-) 在我们的情况下,hybris使用弱证书(并在Java 7上启动,并从架构角度行为像服务器)。因此,为了解决这个问题,我建议您在这里阅读更多关于此问题的信息(https://www.sslshopper.com/article-how-to-create-a-self-signed-certificate-using-java-keytool.html)。你需要做的唯一一件事就是生成一个新的`keystore`(使用**2048**位密钥生成证书,这很**重要**)文件并替换旧文件。最后它可以正常工作。 - Lord Nighton

1

这更可能是因为您的证书链中某个证书,更可能是旧根证书,仍然使用MD2RSA算法进行签名。

您需要在证书存储中找到它并将其删除。

然后回到您的认证机构并要求他们提供新的根证书。

它很可能是具有相同有效期的相同根证书,但已使用SHA1RSA重新认证。

希望这可以帮助您。


0

我在SOAP-UI中遇到了这个问题,以上的解决方案都没有帮助到我。

对我来说合适的解决方案是添加

-Dsoapui.sslcontext.algorithm=TLSv1

在vmoptions文件中(在我的情况下是...\SoapUI-5.4.0\bin\SoapUI-5.4.0.vmoptions)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接