我有一个地图应用程序,可以在给定 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 将正常工作。 MD2
在 SSL 过程中是否在其他地方使用?我在这里错过了什么吗?
原文由 james 发布,翻译遵循 CC BY-SA 4.0 许可协议
背景
MD2 被广泛认为是不安全的,因此在 JDK 6u17 版本的 Java 中被禁用(参见发行说明 http://www.oracle.com/technetwork/java/javase/6u17-141447.html ,“在证书链验证中禁用 MD2”) ,以及 JDK 7,根据您在
java.security
中指出的配置。Verisign 使用的是带有
md2WithRSAEncryption
签名算法的 Class 3 根证书(序列号70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf
),但已弃用它并将其替换为具有相同密钥和名称但使用算法签名的另一个证书sha1WithRSAEncryption
。然而,一些服务器在 SSL 握手期间仍在发送旧的 MD2 签名证书(具有讽刺意味的是,我在 Verisign 运行的服务器上遇到了这个问题!)。您可以通过从服务器 获取证书链 并检查它来验证是否属于这种情况:
openssl s_client -showcerts -connect <server>:<port>
JDK 的最新版本(例如 6u21 和 7 的所有发布版本)应该通过自动删除具有与受信任锚点相同的颁发者和公钥的证书(默认情况下在 cacerts 中)来 解决 此问题。
如果您在使用较新的 JDK 时仍然遇到此问题
检查您是否有自定义信任管理器实现旧的
X509TrustManager
接口。 JDK 7+ 应该与此接口兼容,但是根据我的调查,当信任管理器实现X509TrustManager
而不是更新的X509ExtendedTrustManager
( 文档)时,JDK 使用自己的包装器(AbstractTrustManagerWrapper
) 并以某种方式绕过了针对此问题的内部修复。解决方案是:
使用默认的信任管理器,或者
修改您的自定义信任管理器以直接扩展
X509ExtendedTrustManager
(一个简单的更改)。