我已经编写了TLS代码,该代码正在Java上进行相互身份验证,因此客户端在服务器发送其证书之后发送其证书。我想通过从客户端到服务器端的OCSP验证证书链中的所有证书。
我写的循环逻辑是假设最后一个证书是链中的root(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。
如何强制客户端发送证书链的所有节点?
谢谢
答案 0 :(得分:3)
我意识到作为客户端的Google Chrome浏览器一直在发送证书链而无需root。
那是完全正常的,也是唯一正确的行为。
根证书是信任锚,它必须位于验证证书的一方本地。即使发送了它,在验证证书时也应将其忽略,即仅应使用本地信任锚-否则中间的人只能提供自己的证书链,包括自己的根证书。这意味着在这种情况下,服务器必须已经在本地拥有根证书,因此客户端不需要发送根证书。
换句话说:请勿尝试更改Chrome的行为方式,而应根据正确的行为调整您的期望(和您的代码)。
答案 1 :(得分:0)
我同意史蒂芬(Steffen)的观点,但要给出更多事实,这是TLS 1.3明确说的话:
certificate_list:CertificateEntry结构的序列(链), 每个都包含一个证书和一组扩展名。
和
发件人的证书必须位于第一个 列表中的CertificateEntry。以下每个证书 直接证明紧接其之前的那个。因为 证书验证要求分发信任锚 独立地,指定信任锚的证书可以是 如果知道支持的对等方,则从链中省略 拥有任何遗漏的证书。
最后是订购:
注意:在TLS 1.3之前,每个都需要“ certificate_list”排序 证书以证明紧接其之前的证书;然而, 一些实现允许一些灵活性。服务器有时 发送当前和已弃用的中间件以进行过渡 用途,而其他的只是配置不正确,但是这些 尽管如此,案例仍可得到正确验证。最大化 兼容性,所有实现都应准备好处理 潜在的无关证书和任意命令 TLS版本,但最终实体证书除外 必须是第一位。
因此Chrome浏览器正确应用了此规范。您需要改变自己的目标来应对。