【问题标题】:Is root certificate in the trust store enough to establish a connection?信任库中的根证书是否足以建立连接?
【发布时间】:2019-12-01 12:02:09
【问题描述】:

信任库中的根证书是否足以建立与网站的连接?如果是这样,只是为了测试,我已经将谷歌的根证书导入到我创建并指向该信任存储的新信任存储中。即使这样,我也收到以下异常。 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

但是,如果我尝试使用默认的 java 信任存储连接到谷歌,那么它工作正常。有人可以帮我吗? TIA。

【问题讨论】:

  • 需要整个证书链
  • @Saptarshi Basu 如果是这种情况,那么我可以使用仅包含根 CA 的 java truststore cacerts 建立连接。你能解释一下这是如何工作的吗?
  • 这将帮助您理解:stackoverflow.com/a/53214708/1235935。操作系统和 Java 已经提供了全球认可的 CA 证书链的完整链
  • 不需要链@SaptarshiBasu 使用google证书上方的链中的证书之一就足够了。如果您还想验证主题备用名称字段,则需要链。
  • 您在一个关于包含单个证书的信任库的问题中说“需要整个证书链”,而这不是关于如何配置服务器的问题。如果您不是说整个链都必须在信任库中,那么您应该在受到挑战时这样说,并且无论如何这都无关紧要,因为除非配置错误,否则服务器将交付链。你还是错了;查看对您的答案的评论。

标签: java ssl httpsurlconnection


【解决方案1】:

以下是有关其工作原理的更详细答案:

在 TLS 握手过程中,服务器发送一个形成链的证书列表。在 TLS 1.2 RFC 5246 中解释为:

这是一个证书序列(链)。发件人的证书必须在列表中排在第一位。后面的每个证书必须直接证明它前面的证书。因为证书验证需要独立分发根密钥,所以可以从链中省略指定根证书颁发机构的自签名证书,假设远程端必须已经拥有它才能在任何情况下验证它。

证书的根始终是自签名的,对于全球接受的根 CA(证书颁发机构),证书存储在客户端平台(即 Mozilla、MacOS、Java、Android、Windows 等)中。因此服务器不需要发送这个证书。

同样的 RFC 还提到:

实现负责验证证书的完整性,并且通常应支持证书撤销消息。应始终验证证书以确保由受信任的证书颁发机构 (CA) 正确签名。应非常谨慎地选择和添加受信任的 CA。用户应该能够查看有关证书和根 CA 的信息。

换句话说,平台实现将遍历证书链并不断验证证书,直到找到信任存储中的证书。信任存储中存在的任何证书都不会被验证,并将被假定为受信任的证书。

这在 TLS 1.3 RFC 8446 中提到:

实现负责验证证书的完整性,并且通常应支持证书撤销消息。如果没有来自应用程序配置文件的特定指示,则应始终验证证书以确保由受信任的证书颁发机构 (CA) 正确签名。信任锚的选择和添加应该非常谨慎。用户应该能够查看有关证书和信任锚的信息。

它进一步说:

自签名证书或信任锚证书上的签名未经过验证,因为它们开始了一条证书路径

现在,以 Google 为例,如果我们在 https://www.ssllabs.com/ 中测试服务器,我们可以看到证书 www.google.comGTS CA 101 是由服务器发送的,而 GlobalSign 证书存在于信任库中平台。

希望这能澄清我之前的 cmets。

【讨论】:

  • 这也不正确。它不必是根证书。 ClientHello 消息包含受信任的颁发者,服务器只需发送其链中以受信任的颁发者签名的证书终止的那部分。受信任的发行者不必是链的根。例如,它可能是服务器自己的证书。
  • @user207421 如果您刚刚阅读了该段,您会看到提到的内容以及它说“它遍历链直到它遇到信任存储中的证书”跨度>
【解决方案2】:

我刚刚尝试为 google.com 构建一个 https 获取请求。已加载 GlobalSign 证书。 Google 的证书是由这个 CA 签名的,所以 ssl 握手应该可以通过。下面是我使用的代码,它可以工作。

    @Test
    public void callGoogleWithRootCA() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, KeyManagementException {
        String trustStorePath = "keystores-for-unit-tests/truststore.jks";
        String trustStorePassword = "secret";

        KeyStore trustStore;

        try(InputStream keystoreInputStream = this.getClass().getClassLoader().getResourceAsStream(trustStorePath)) {
            if (isNull(keystoreInputStream)) {
                throw new RuntimeException(String.format("Could not find the keystore file with the given location %s", trustStorePath));
            }

            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystore.load(keystoreInputStream, trustStorePassword.toCharArray());
            trustStore = keystore;
        }

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);

        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

        HttpsURLConnection connection = (HttpsURLConnection) new URL("https://www.google.com").openConnection();
        connection.setSSLSocketFactory(sslContext.getSocketFactory());
        connection.setRequestMethod("GET");
        String responseBody = IOUtils.toString(connection.getInputStream(), StandardCharsets.UTF_8);
        int responseCode = connection.getResponseCode();

        assertThat(responseCode).isEqualTo(200);
    }

在此处查看密钥库文件中的特定证书:

我无法在此处上传密钥库文件,但这是我用于将证书导入新密钥库的 pem 文件:

-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----

在握手过程中,我得到以下信息:

javax.net.ssl|DEBUG|01|main|2019-12-02 01:29:04.529 CET|CertificateMessage.java:358|Consuming server Certificate handshake message (
"Certificates": [
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "75 20 46 4B 8D AC DC 10 08 00 00 00 00 1D 8A 52",
    "signature algorithm": "SHA256withRSA",
    "issuer"             : "CN=GTS CA 1O1, O=Google Trust Services, C=US",
    "not before"         : "2019-11-05 08:46:45.000 CET",
    "not  after"         : "2020-01-28 08:46:45.000 CET",
    "subject"            : "CN=www.google.com, O=Google LLC, L=Mountain View, ST=California, C=US",
    "subject public key" : "EC",
    "extensions"         : [
      {
        ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false
      },
      {
        ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
        AuthorityInfoAccess [
          [
           accessMethod: ocsp
           accessLocation: URIName: http://ocsp.pki.goog/gts1o1
        , 
           accessMethod: caIssuers
           accessLocation: URIName: http://pki.goog/gsr2/GTS1O1.crt
        ]
        ]
      },
      {
        ObjectId: 2.5.29.35 Criticality=false
        AuthorityKeyIdentifier [
        KeyIdentifier [
        0000: 98 D1 F8 6E 10 EB CF 9B   EC 60 9F 18 90 1B A0 EB  ...n.....`......
        0010: 7D 09 FD 2B                                        ...+
        ]
        ]
      },
      {
        ObjectId: 2.5.29.19 Criticality=true
        BasicConstraints:[
          CA:false
          PathLen: undefined
        ]
      },
      {
        ObjectId: 2.5.29.31 Criticality=false
        CRLDistributionPoints [
          [DistributionPoint:
             [URIName: http://crl.pki.goog/GTS1O1.crl]
        ]]
      },
      {
        ObjectId: 2.5.29.32 Criticality=false
        CertificatePolicies [
          [CertificatePolicyId: [2.23.140.1.2.2]
        []  ]
          [CertificatePolicyId: [1.3.6.1.4.1.11129.2.5.3]
        []  ]
        ]
      },
      {
        ObjectId: 2.5.29.37 Criticality=false
        ExtendedKeyUsages [
          serverAuth
        ]
      },
      {
        ObjectId: 2.5.29.15 Criticality=true
        KeyUsage [
          DigitalSignature
        ]
      },
      {
        ObjectId: 2.5.29.17 Criticality=false
        SubjectAlternativeName [
          DNSName: www.google.com
        ]
      },
      {
        ObjectId: 2.5.29.14 Criticality=false
        SubjectKeyIdentifier [
        KeyIdentifier [
        0000: 63 55 73 A0 9D C3 D5 FA   3C 1A 17 EA 0B 72 AB EF  cUs.....<....r..
        0010: D3 15 15 BB                                        ....
        ]
        ]
      }
    ]},
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "01 E3 B4 9A A1 8D 8A A9 81 25 69 50 B8",
    "signature algorithm": "SHA256withRSA",
    "issuer"             : "CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2",
    "not before"         : "2017-06-15 02:00:42.000 CEST",
    "not  after"         : "2021-12-15 01:00:42.000 CET",
    "subject"            : "CN=GTS CA 1O1, O=Google Trust Services, C=US",
    "subject public key" : "RSA",
    "extensions"         : [
      {
        ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
        AuthorityInfoAccess [
          [
           accessMethod: ocsp
           accessLocation: URIName: http://ocsp.pki.goog/gsr2
        ]
        ]
      },
      {
        ObjectId: 2.5.29.35 Criticality=false
        AuthorityKeyIdentifier [
        KeyIdentifier [
        0000: 9B E2 07 57 67 1C 1E C0   6A 06 DE 59 B4 9A 2D DF  ...Wg...j..Y..-.
        0010: DC 19 86 2E                                        ....
        ]
        ]
      },
      {
        ObjectId: 2.5.29.19 Criticality=true
        BasicConstraints:[
          CA:true
          PathLen:0
        ]
      },
      {
        ObjectId: 2.5.29.31 Criticality=false
        CRLDistributionPoints [
          [DistributionPoint:
             [URIName: http://crl.pki.goog/gsr2/gsr2.crl]
        ]]
      },
      {
        ObjectId: 2.5.29.32 Criticality=false
        CertificatePolicies [
          [CertificatePolicyId: [2.23.140.1.2.2]
        [PolicyQualifierInfo: [
          qualifierID: 1.3.6.1.5.5.7.2.1
          qualifier: 0000: 16 1C 68 74 74 70 73 3A   2F 2F 70 6B 69 2E 67 6F  ..https://pki.go
        0010: 6F 67 2F 72 65 70 6F 73   69 74 6F 72 79 2F        og/repository/

        ]]  ]
        ]
      },
      {
        ObjectId: 2.5.29.37 Criticality=false
        ExtendedKeyUsages [
          serverAuth
          clientAuth
        ]
      },
      {
        ObjectId: 2.5.29.15 Criticality=true
        KeyUsage [
          DigitalSignature
          Key_CertSign
          Crl_Sign
        ]
      },
      {
        ObjectId: 2.5.29.14 Criticality=false
        SubjectKeyIdentifier [
        KeyIdentifier [
        0000: 98 D1 F8 6E 10 EB CF 9B   EC 60 9F 18 90 1B A0 EB  ...n.....`......
        0010: 7D 09 FD 2B                                        ...+
        ]
        ]
      }
    ]}
]
)
javax.net.ssl|DEBUG|01|main|2019-12-02 01:29:04.566 CET|X509TrustManagerImpl.java:242|Found trusted certificate (
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "04 00 00 00 00 01 0F 86 26 E6 0D",
    "signature algorithm": "SHA1withRSA",
    "issuer"             : "CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2",
    "not before"         : "2006-12-15 09:00:00.000 CET",
    "not  after"         : "2021-12-15 09:00:00.000 CET",
    "subject"            : "CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2",
    "subject public key" : "RSA",
    "extensions"         : [
      {
        ObjectId: 2.5.29.35 Criticality=false
        AuthorityKeyIdentifier [
        KeyIdentifier [
        0000: 9B E2 07 57 67 1C 1E C0   6A 06 DE 59 B4 9A 2D DF  ...Wg...j..Y..-.
        0010: DC 19 86 2E                                        ....
        ]
        ]
      },
      {
        ObjectId: 2.5.29.19 Criticality=true
        BasicConstraints:[
          CA:true
          PathLen:2147483647
        ]
      },
      {
        ObjectId: 2.5.29.31 Criticality=false
        CRLDistributionPoints [
          [DistributionPoint:
             [URIName: http://crl.globalsign.net/root-r2.crl]
        ]]
      },
      {
        ObjectId: 2.5.29.15 Criticality=true
        KeyUsage [
          Key_CertSign
          Crl_Sign
        ]
      },
      {
        ObjectId: 2.5.29.14 Criticality=false
        SubjectKeyIdentifier [
        KeyIdentifier [
        0000: 9B E2 07 57 67 1C 1E C0   6A 06 DE 59 B4 9A 2D DF  ...Wg...j..Y..-.
        0010: DC 19 86 2E                                        ....
        ]
        ]
      }
    ]}
)

回到你的问题,可能你的密钥库没有加载。您能否验证您的密钥库文件是否为空?

【讨论】:

  • 谢谢,现在一切正常,我尝试创建新的信任库。
【解决方案3】:

对于 Saptarshi Basu 的回答,抱歉位 TLDR。用我的外行的话来说

  • 如果您信任存储只有根证书,则服务器必须发送链
  • 如果您的信任存储有链(因此包括中间证书),服务器可以 仅发送已颁发的证书

疑难解答 https://gist.github.com/4ndrej/4547029#file-sslpoke-javaopenssl(它使用操作系统证书存储)

openssl version -d
openssl s_client -connect google.com:443 -showcerts

【讨论】:

    猜你喜欢
    • 2019-02-26
    • 2010-09-26
    • 2022-08-10
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    相关资源
    最近更新 更多