强制Chrome在TLS期间发送链中的所有证书

问题描述 投票:1回答:2

我编写了一个TLS代码,它在Java上进行相互身份验证,因此客户端在服务器发送证书后发送证书。我想验证OCSP证书链中的所有证书,它来自客户端到服务器端。

我编写了我的循环逻辑,假设最后一个证书是链中的根(CA)证书,而不是为它发送任何OCSP查询;

        int certificateChainSize= x509Certificates.length;

        // Verifies certificate chain respectively (issuer certificate required).
        CertificateResult response = null;

        try {
            for (int i = 0; i < certificateChainSize-1 ; i++) {
                response = client.verify(x509Certificates[i], x509Certificates[i+1]);
            }
        } catch (OcspException e) {
            e.printStackTrace();
        }

当我测试TLS并获得Wireshark捕获时,我意识到Google Chrome作为客户端一直在发送没有root的证书链。结果是;由于循环逻辑,因此我的代码假定中间证书是root,因此不会查询中间证书。

如何强制客户端发送证书链的所有节点?

谢谢

ssl certificate ssl-certificate ocsp
2个回答
3
投票

我意识到谷歌Chrome作为客户端一直在发送没有root的证书链。

这是完全正常的,也是唯一正确的行为。

根证书是信任锚,它必须是验证证书的一方的本地。即使它是发送,在验证证书时也应忽略它,即只应使用本地信任锚 - 否则中间的人可以提供他自己的证书链,包括他自己的根证书。这意味着在这种情况下,服务器必须已在本地拥有根证书,因此客户端无需发送它。

换句话说:不要试图改变Chrome的行为方式,而是根据正确的行为调整您的期望(和您的代码)。


0
投票

我同意Steffen的观点,但是为了提供更多的事实,TLS 1.3明确表示:

certificate_list:CertificateEntry结构的序列(链),每个结构包含一个证书和一组扩展。

发件人的证书必须位于列表中的第一个CertificateEntry中。以下每个证书都应该直接证明其前面的证书。由于证书验证要求独立分发信任锚,因此可以从链中省略指定信任锚的证书,前提是已知支持的对等方拥有任何省略的证书。

最后订购:

注意:在TLS 1.3之前,“certificate_list”命令要求每个证书对其前面的证书进行认证;但是,一些实现允许一些灵活性。服务器有时会为过渡目的发送当前和已弃用的中间件,而其他服务器的配置不正确,但这些情况仍然可以正确验证。为了获得最大的兼容性,所有实现都应该准备好处理来自任何TLS版本的潜在无关证书和任意排序,但必须首先是最终实体证书。

因此Chrome正确应用此规范。你需要改变你的目标来应对它。

© www.soinside.com 2019 - 2024. All rights reserved.