【问题标题】:Unable to authenticate to SSL site in java: "pathLenConstraint violated - this cert must be the last cert in the certification path"无法在 Java 中对 SSL 站点进行身份验证:“违反了 pathLenConstraint - 此证书必须是证书路径中的最后一个证书”
【发布时间】:2010-10-24 04:36:10
【问题描述】:

我正在尝试使用 Java 代码从安全(即 SSL)网页中读取内容。 我正在尝试同时使用 URLConnection (java.net) 和 Apache 的 HTTPClient。 在这两种情况下,当我提出请求时,我都会收到以下异常:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX 路径验证失败: java.security.cert.CertPathValidatorException: 基本约束检查失败: 违反了 pathLenConstraint - 此证书 必须是最后一个证书 认证路径在 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1518) 在 com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174) 在 com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106) 在 com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495) 在 com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:818) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1030) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1057) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1041) 在 sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402) 在 sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) 在 sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:934) 在 sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234) 在 com.sap.river.coghead.rest.Main.testJavaHTTPConnection(Main.java:45) 在 com.sap.river.coghead.rest.Main.main(Main.java:32) 造成的: sun.security.validator.ValidatorException: PKIX 路径验证失败: java.security.cert.CertPathValidatorException: 基本约束检查失败: 违反了 pathLenConstraint - 此证书 必须是最后一个证书 认证路径在 sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:187) 在 sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:139) 在 sun.security.validator.Validator.validate(Validator.java:203) 在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172) 在 com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841) ... 13 更多原因: java.security.cert.CertPathValidatorException: 基本约束检查失败: 违反了 pathLenConstraint - 此证书 必须是最后一个证书 认证路径在 sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139) 在 sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:316) 在 sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178) 在 java.security.cert.CertPathValidator.validate(CertPathValidator.java:206) 在 sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:182) ... 18 更多

请注意,我已经成功地建立了一个非 ssl 连接,但连接到不同的主机。 我还可以使用浏览器查看此页面 - 证书已在此处正确验证。

在从服务器检索证书时,您是否需要以某种方式更改证书的顺序? 有没有我遗漏的配置?

提前致谢,

里尔

【问题讨论】:

    标签: java http ssl


    【解决方案1】:

    我进一步挖掘,答案在于我需要将必要的证书导入到 JVM 用来验证 SSL 的密钥库中。 密钥库是 jre 中用于运行程序的 jre/lib/security 文件夹下的“cacerts”文件。

    我手动导出了网站的证书 - 全部。
    然后我使用 Sun 提供的“keytool”实用程序将它导入我的默认密钥库。请注意,您必须以正确的顺序导入它们。
    然后,我使用新的密钥库而不是 JRE 的密钥库 - 它起作用了。

    我想将证书直接导入 JRE 的密钥库会更好,但该工具要求我输入我不知道的密码。

    我相信还有一种方法可以更轻松地解决这个问题,只是还没有找到。我很乐意得到一些指示(JSSE 中的 TrustManager 类?)。

    最后,一些功劳。这个帖子在这里:http://javaishdiscoveries.blogspot.com/2009/02/battle-with-cacerts-and-https.html 帮助我指出了正确的方向。

    【讨论】:

    • 我不知道这是否有帮助,但 Java 允许您更改默认的 SLLSocketFactory。
    • 是的,我想我需要在那个领域做点什么。只需要进一步调查。无论如何,谢谢 - Lior
    • 仅供参考,默认 Java 证书密钥库 $JAVA_HOME/lib/security/cacerts 的密码是 'changeit'
    【解决方案2】:

    javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径验证失败:java.security.cert.CertPathValidatorException:基本约束检查失败:违反了 pathLenConstraint - 此证书必须是证书中的最后一个证书路径在

    pathLenConstraint

    请参阅(关于证书链的说明)

    http://groups.google.com/group/google-checkout-developers-forum/web/google-checkout-and-ssl-certificates?version=49

    google 说证书链顺序可能有问题,我刚刚发现我的证书不正常,尚未修复,正在处理中。我稍后会更新。


    旧帖:

    几乎有同样的问题。

    将证书手动添加到密钥库会有所帮助,但我更愿意与我的客户一起自动完成。

    所以我的解决方案:

    我将只为这个应用程序和一个主机使用密钥库 1. keystore 不存在 - 使用一些生成的密码创建 2. 将密码保存在配置文件中 3.询问用户(或不)他是否愿意接受这个证书 4. 如果是 - 将其保存到密钥库,并在需要时使用它

    这是一个好的解决方案吗?有cmets吗?

    【讨论】:

      【解决方案3】:

      问题出在证书链顺序上。 它是:A->C->B,但应该是 A->B->C,一旦我们固定了链顺序,应用程序就开始工作了。


      我还没有亲自修复证书。但这篇文章很有帮助

      http://groups.google.com/group/google-checkout-api-troubleshooting/browse_thread/thread/99862c11d37d3127

      【讨论】:

      • 你是怎么知道证书的链序的?
      猜你喜欢
      • 2013-08-04
      • 1970-01-01
      • 2019-01-03
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2017-03-16
      相关资源
      最近更新 更多