SSLHandshakeException - java.security.cert.CertPathValidatorException:需要非空策略树且策略树为空
Posted
技术标签:
【中文标题】SSLHandshakeException - java.security.cert.CertPathValidatorException:需要非空策略树且策略树为空【英文标题】:SSLHandshakeException - java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null 【发布时间】:2014-02-23 20:08:48 【问题描述】:我的信任库中有服务器根证书,在设置 -Djavax.net.debug=all 后,我可以看到信任库已初始化并且受信任的证书在那里:
trustStore is: test.truststore
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
Subject: CN=Test Root, OU=test, O=test, C=us
Issuer: CN=Test Root, OU=test, O=test, C=us
Algorithm: RSA; Serial number: 0x1
Valid from Thu Sep 05 14:49:45 GMT+00:00 2013 until Sun Sep 05 14:49:45 GMT+00:00 2021
接下来我可以在服务器证书链中看到受信任的证书:
chain [2] = [
[
Version: V3
Subject: CN=Test Root, OU=test, O=test, C=us
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 2048 bits
modulus: 259491476017...etc
public exponent: 65537
Validity: [From: Thu Sep 05 14:49:45 GMT+00:00 2013,
To: Sun Sep 05 14:49:45 GMT+00:00 2021]
Issuer: CN=Test Root, OU=test, O=test, C=us
SerialNumber: [ 01]
但由于某种原因,握手仍然失败:
%% Invalidated: [Session-1, TLS_RSA_WITH_AES_256_CBC_SHA]
Thread-2, SEND TLSv1 ALERT: fatal, description = certificate_unknown
Thread-2, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 2E .......
Thread-2, called closeSocket()
Thread-2, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
Thread-2, IOException in getSession(): javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
“需要非空策略树且策略树为空”是什么意思?
【问题讨论】:
如果没有工作代码示例,将很难回答您的问题。请将您的代码发布为 minimal example,以证明您的问题。 【参考方案1】:当应用程序尝试验证具有 Require Explicit Policy:0
的链(就像 DoD 中间体所做的那样)并在 certPath 和 PKIXParameters 中包含自签名证书作为信任锚时,我看到了这个问题。类似于:
CertPath certPath = CertificateFactory.getInstance("X.509").generateCertPath(chain);
X509Certificate ca = (X509Certificate)chain.get(chain.size() - 1);
TrustAnchor trustAnchor = new TrustAnchor((X509Certificate)ca, null);
PKIXParameters params = new PKIXParameters(Collections.singleton(trustAnchor));
我没有用 SSLSocket 尝试过这个,但我假设如果服务器发送根,你可能会看到它(他们真的不应该)。我认为一个有效的解决方法是查看最终证书是否为SelfIssued (getSubjectX500Principal() equals getIssuerX500Principal()
),并在调用验证器之前将其从链中删除。类似于:
if (ca.getSubjectX500Principal().equals(ca.getIssuerX500Principal()))
chain.remove(ca);
未经 SSL 测试,但它在验证从 PEM 文件中读取的私钥 + 完整链时对我有用。
BouncyCastle 堆栈跟踪与 sun 提供程序相比:
java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:233)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:141)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:80)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
at test.main(test.java:52)
Caused by: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
at sun.security.provider.certpath.PolicyChecker.processPolicies(PolicyChecker.java:572)
at sun.security.provider.certpath.PolicyChecker.checkPolicy(PolicyChecker.java:225)
at sun.security.provider.certpath.PolicyChecker.check(PolicyChecker.java:180)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
... 5 more
org.bouncycastle.jce.exception.ExtCertPathValidatorException: No valid policy tree found when one expected.
at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertF(Unknown Source)
at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown Source)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
at test.main(test.java:53)
【讨论】:
以上是关于SSLHandshakeException - java.security.cert.CertPathValidatorException:需要非空策略树且策略树为空的主要内容,如果未能解决你的问题,请参考以下文章
Scala:如何忽略“SSLHandshakeException”
SSLHandshakeException 无法验证用户身份
SSLHandshakeException:不存在主题替代名称