gpt4 book ai didi

java - JCE:验证 X509 自签名证书时出现异常

转载 作者:太空宇宙 更新时间:2023-11-03 13:34:10 25 4
gpt4 key购买 nike

我们为 SSL/TLS 开发了自定义 JCE 安全提供程序。

我们的一位用户在客户端遇到服务器证书验证失败。这是常见的“无法找到请求目标的有效证书路径”错误。 (是的,证书在信任库中。)

注意:虽然我们正在实现自定义提供程序,但我们依赖于信任管理器的标准 JCE 提供程序,在 TLS 握手期间使用 javax.net.ssl.X509TrustManager.checkServerTrusted(X509Certificate[] chain, String)。

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:105)
[snip]
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:146)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
...

与我们所有的用户一样,他们安装了无限的安全策略 jar。

服务器证书是自签名的(不是 CA)。他们使用 127.0.0.1 作为主机名,因为他们只是连接到后端进程。

JRE/JDK 的默认安装有效(使用 Sun/Oracle 安全提供程序)。使用 javax.net.debug 输出,我已确认这些成功的连接使用相同的自签名证书。

但是,当我将一些代码组合在一起以简单地建立连接时,它可以在同一台机器上使用相同的信任库、 keystore 、证书和 JDK 毫无问题地工作。这使用相同的验证功能,该功能使用相同的证书和相同的 authType 字符串对 X509TrustManager.checkServerTrusted() 进行相同的调用。我一辈子都无法解释为什么 checkServerTrusted() 在这种情况下验证了证书,但在用户的情况下却失败了。

是否有可能通过某种方式调整 JCE,使 X509TrustManager 无法验证此证书?也许是因为它是自签名的,或者因为公用名是服务的名称而不是域名?我在他们的 JVM 参数或安全属性中看不到任何表明这一点的内容。但也许他们正在进行一些 JCE 调用,我不知道哪些会修改 X509TrustManager 的行为?

证书的 javax.net.debug 输出如下。通用名称只是我们采用者服务的名称。这对我来说似乎可疑。但是,它适用于默认安全提供程序。

***
Found trusted certificate:
[
[
Version: V3
Subject: CN=[snip], OU=[snip], O=[snip], L=Bangalore, ST=[snip], C=IN
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

Key: Sun RSA public key, 2048 bits
modulus: [snip]
public exponent: 65537
Validity: [From: Wed Feb 17 14:45:40 IST 2016,
To: Thu Nov 20 14:45:40 IST 2070]
Issuer: CN=[snip], OU=[snip], O=[snip], L=Bangalore, ST=[snip], C=IN
SerialNumber: [ 5cf68160]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
[snip]
]
]

]
Algorithm: [SHA256withRSA]
Signature:
[snip]

]

添加一些额外的日志后,很明显无论出于何种原因,接受的颁发者都以不同的方式填充。在失败的情况下,从 [trust-manager].getAcceptedIssuers[] 返回大量已接受的发行者;他们不包括有问题的证书。在通过的情况下,只有有问题的证书包含在接受的颁发者中。

[编辑 1] 更正了证书。

[编辑 2] 更正了粗体问题中的通用名称。

[edit 3] 添加了接受的发行人段落

最佳答案

事实证明这是缓存信任管理器的问题。

使用默认提供程序或我们的自定义提供程序,信任管理器最初使用 cacerts 信任库进行实例化。

使用默认提供程序,稍后使用 javax.net.ssl.trustStore 指定的信任库实例化新的信任管理器。我们的自定义提供程序只是重新使用之前实例化的 cacerts 信任管理器。

解决方案:实例化一个新的信任管理器,它将遵循 javax.net.ssl.trustStore。

关于java - JCE:验证 X509 自签名证书时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45424160/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com