【问题标题】:TLS client authenticationTLS 客户端身份验证
【发布时间】:2016-07-09 21:00:13
【问题描述】:

TLS(v1.1、1.2 等)或 X.509 标准是否规定了客户端和服务器需要如何协商客户端身份验证证书?

具体来说,我正在处理服务器在其证书请求消息中发送一堆(大约五个)证书颁发机构的情况,如下所示:

*** CertificateRequest
Cert Types: RSA, DSS
Cert Authorities:
<CN=AA, DC=BB, DC=cc, DC=dd>
<CN=EE, DC=FF, DC=gg, DC=hh>
<CN=II, DC=JJ, DC=kk, DC=ll>
<CN=MM, DC=NN, DC=oo, DC=pp>

客户端密钥库具有多个客户端证书,这些证书与从服务器接收的这些证书颁发机构之一匹配(由这些证书颁发机构颁发)。

我看到我的客户端选择并使用了密钥库中与服务器的受信任 CA 匹配的第一个证书(在众多证书中)。但是,服务器将不接受此证书。服务器将接受的证书存在于客户端密钥库中,但它不是与服务器的证书请求标准匹配的证书列表中的第一个。服务器终止连接并且不发送任何警报。

现在我有两个问题:

  1. 是我的客户端或服务器行为不端吗?

  2. 对于客户端-服务器在放弃连接之前尝试所有匹配的客户端证书,TLS 规范有什么要说的吗?

如果 TLS 规范对此一无所知 - 通常如何最好地解决这个问题?向客户端添加智能(例如,通过指定别名或其他一些此类选择机制)是解决此问题的唯一方法吗?为什么 TLS 协议不能自己处理?

我已经阅读了 TLS 规范以及我可以在网上搜索到的任何 X.509 信息(诚然并非详尽无遗),但我没有得到明确的信息。

【问题讨论】:

  • 如果服务器不接受 CA 签名的证书,为什么还要宣传 CA?
  • 在这种情况下,每个客户端用户都被分配了一个特定的密钥+证书以用于身份验证。但是,客户端密钥库包含用于其他目的的证书以及公共密钥库中的此身份验证证书。所有证书都由服务器公布的 CA 签名。服务器显然正在对证书执行二次检查(除了它是由它信任的 CA 签名的),以确认它确实是用于客户端身份验证的证书。

标签: authentication ssl client x509


【解决方案1】:

是我的客户端或服务器行为不端吗?

根据您的描述,服务器请求由特定 CA 签名的证书,客户端发送这样的证书,但服务器随后不接受它。原因可能是证书错误、签名不安全、已过期、被撤销或类似情况,在这种情况下客户端不应该发送它。或者可能是服务器错误地不接受完全有效的证书。从您的描述中无法判断是哪种情况。

TLS 规范对客户端-服务器在放弃连接之前尝试所有匹配的客户端证书有什么规定吗?

不,它希望客户端在第一次尝试时发送一个符合服务器要求的有效证书,并希望服务器接受这个有效证书。客户端的一个常见行为是询问用户,如果多个证书与服务器的广告要求相匹配,则应使用哪个证书。

【讨论】:

  • 所有证书均有效。客户端发送的用于身份验证的密钥用法如下:[Key_Encipherment, Data_Encipherment]。虽然一台服务器预期具有关键用途:[DigitalSignature]。客户端是否未能按照 TLS 规范根据密钥使用情况选择正确的证书?
  • 顺便说一下,这里的客户端依赖于来自 Java Runtime 的 TLS 实现 - 没有自定义。
  • @VinJ:因为客户端证书不用于加密而仅用于身份验证,所以我会说它需要 DigitalSignature 而不是其他证书。另见security.stackexchange.com/questions/68491/…