java.security.cert.CertificateException:证书不符合算法约束

Posted

技术标签:

【中文标题】java.security.cert.CertificateException:证书不符合算法约束【英文标题】:java.security.cert.CertificateException: Certificates does not conform to algorithm constraints 【发布时间】:2012-12-18 10:38:07 【问题描述】:

我有一个地图应用程序,可以在给定 URL 的情况下添加 ArcGIS 9.3+ 基本地图。我要添加的 URL 之一来自客户的 URL,并且是安全的。我的地图应用程序之前使用的是 Java 6,并且能够毫无问题地添加安全 URL。我现在升级到 Java 7 并获得了

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

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

"jdk.certpath.disabledAlgorithms=MD2"

但是当我检查该 URL 的 Certification Signature Algorithm 时,它显示为 SHA-1。更奇怪的是,如果我注释掉java.security 文件中的"jdk.certpath.disabledAlgorithms=MD2" 行,URL 将毫无问题地工作。在 SSL 过程中,MD2 是否在其他地方使用过?我在这里遗漏了什么吗?

【问题讨论】:

在使用 512 位 RSA 密钥时遇到此异常。我的java.security 文件有jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024。我正在使用 OpenJDK 7。 【参考方案1】:

背景

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

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

您可以通过来自服务器的getting the certificate chain 并检查它来验证是否是这种情况:

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

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

如果您在使用较新的 JDK 时仍然存在此问题

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

解决办法是:

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

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

【讨论】:

你能看看我的(非常相似的)question吗? 不仅 openssl s_client ... 命令非常有用,而且解决我 6 小时痛苦和痛苦的方法是 X509ExtendedTrustManager 更改。 更改为 X509ExtendedTrustManager 是有史以来最好的解决方案。非常感谢。【参考方案2】:

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

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

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

警告 请记住,这可能会产生安全隐患,因为禁用的算法被认为是弱算法。 作为替代方案,workaround 可以通过命令行选项在 JVM 基础上应用,以使用具有此更改的外部 java.security 文件,例如:@ 987654322@ 对于 Eclipse,在 -vmargs-Djava.security.properties=/etc/sysconfig/noMD5.java.security

下的 eclipse.ini 上添加一行

原键

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 中的相同 不确定,但看起来与 SSLCipherSuite 指令有关。看看这里httpd.apache.org/docs/current/mod/mod_ssl.html。查找此字符串:RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5 更改对我不起作用,我不得不注释掉这两行【参考方案3】:

在 Fedora 28 上,只需注意一行

security.useSystemPropertiesFile=true

java.security 文件,位于:

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

Fedora 28 在

引入了 disabledAlgorithms 控件的外部文件

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

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

security.useSystemPropertiesFile=false

【讨论】:

我在使用 Dbeaver 和 MS SQL JDBC 6.0 - 6.4 时遇到了这个问题。这个解决方案对我有用,但设置 -Djdk.tls.client.protocols=TLSv1 没有。 我在 Fedora 28 上遇到问题,RSA 密钥小于 1024 的证书被拒绝 - 我从 /etc/crypto-policies/back-ends/java.config 中删除了该异常,现在它工作正常。谢谢。 谢谢你,这为我在 Fedora 30 上修复了它。 我在 Centos 8 和 RHEL 8 上遇到了这个问题,它们现在也有加密策略。【参考方案4】:

我们无法控制的一个数据库存在这个问题,它需要另一种解决方案(此处列出的那些不起作用)。我需要:

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

我认为就我而言,这与强制执行某个命令有关。

【讨论】:

这是帮助我对抗 DavMail 的“证书不符合算法约束”异常的唯一解决方案。必须修改 /usr/bin/davmail 脚本以添加该选项。【参考方案5】:

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

【讨论】:

【参考方案6】:

这更有可能发生,因为在您的证书链的某个地方,您有一个证书,更有可能是一个旧的根,它仍然使用 MD2RSA 算法进行签名。

您需要将其定位到您的证书存储区并将其删除。

然后返回您的证书颁发机构并要求他们提供新的根目录。

它更有可能是具有相同有效期但已通过 SHA1RSA 重新认证的同一个根。

希望对您有所帮助。

【讨论】:

【参考方案7】:

同事。

我在为我们的 REST API 开发自动化测试时遇到了这个问题。 JDK 7_80 仅安装在我的机器上。在我安装 JDK 8 之前,一切正常,我有可能使用JMeter 获得 OAuth 2.0 令牌。在我安装 JDK 8 之后,Certificates does not conform to algorithm constraints 的噩梦开始了。

JMeter 和 Serenity 都无法获得令牌。 JMeter 使用 JDK 库来发出请求。当库调用连接到使用它的端点时,库只会引发异常,而忽略请求。

接下来是注释 ALL java.security 文件中所有用于disabledAlgorithms 的行。

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 开始,从架构的角度来看就像服务器一样)看法)。所以,为了解决这个问题,我建议你在这里阅读更多关于这个问题的信息 (sslshopper.com/…)。您唯一需要做的就是生成一个新的keystore(使用2048 位密钥生成证书,它的important)文件并替换旧文件。最后它工作得很好。【参考方案8】:

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

对我来说正确的解决方案是添加

-Dsoapui.sslcontext.algorithm=TLSv1

在 vmoptions 文件中(在我的例子中是 ...\SoapUI-5.4.0\bin\SoapUI-5.4.0.vmoptions)

【讨论】:

【参考方案9】:

在 docker 中使用 openjdk-7 我已经挂载了一个内容为 https://gist.github.com/dtelaroli/7d0831b1d5acc94c80209a5feb4e8f1c#file-jdk-security 的文件

#Location to mount
/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/java.security

谢谢@luis-muñoz

【讨论】:

以上是关于java.security.cert.CertificateException:证书不符合算法约束的主要内容,如果未能解决你的问题,请参考以下文章