相互 SSL:unsupported_certificate 和客户端证书格式

Mutual SSL: unsupported_certificate and client certificate format

我被告知使用双向身份验证连接到客户的服务器。服务器身份验证工作顺利,但我们在获取客户端身份验证方面遇到了巨大的麻烦。让我试着解释一下我们的麻烦。

前段时间我公司在GeoTrust买了一个证书,这个证书应该是完全有效的,可以用作我们的客户证书。显然,客户没有设法将此 GeoTrust 证书适当地添加到他们的信任库中,因此每次我们尝试连接到他们的服务器时,我们都会在 SSL 握手日志中看到错误 unknown_ca .

相反,客户要求我们向他们发送证书签名请求 (csr),我们收到了根证书以及应该用作我们的客户端证书的证书。在相应地更新了我们的密钥库之后,我们现在在 SSL 握手日志中看到错误 unsupported_certificate。仔细查看客户签名的客户端证书会发现新证书明确具有 Server Authentication 扩展名,但没有 Client Authentication 扩展名。我发现 unsupported_certificate 和缺失的 Client Authentication 扩展之间的相关性非常明显,但客户拒绝接受缺失的 Client Authentication 作为一个有效的解释(因此拒绝为我们创建一个新的和适当扩展的客户端证书)。客户是这样争论的:

客户从他的日志中向我发送了未返回证书的屏幕截图,并声称此日志条目意味着我正在通过网络传递客户端证书格式错误:

为了加强他关于我以错误格式提交客户端证书的断言,客户向我发送了以下 TCP 转储屏幕截图,其中 pkcs 已被圈出:

据我所知,pkcs-9-at-emailAddress 只是在证书中包含电子邮件地址信息的标准方式,与证书无关以错误的格式提交。此外,我在 Google 中找到了一个地方,其中提到 没有返回证书 日志条目可能发生在客户端证书丢失 Client 的情况下身份验证 扩展。

为了排除是keystore.jkstruststore.jks被我们Java 格式错误的代码,我尝试仅使用 OpenSSL 命令连接到他们的服务器:

openssl s_client -CAfile caroot.cer -cert client.cer -key client.key -connect <host>:<port>

执行此 OpenSSL 命令会导致完全相同的 unsupported_certificate 错误。

如果有人能帮助我理解我们是对的还是客户是对的,我将不胜感激。非常感谢。

当然 OpenSSL s_client 将以正确的格式传输证书(否则它将在连接到服务器之前失败)。让我们检查一下为 TLS 1.2 (RFC 5246).

定义的 Error Alerts
bad_certificate
   A certificate was corrupt, contained signatures that did not
   verify correctly, etc.

unsupported_certificate
   A certificate was of an unsupported type.

还有几个警报,但这是最有趣的两个。由此我们可以推断出解析证书失败,例如由于格式不正确会导致 bad_certificate,并且在 密钥使用 信息不合适等情况下可能会返回 unsupported certificate

如果您的客户需要进一步的证据,您可以将 s_server(1) 程序与 s_client 一起使用,以表明在此设置中客户证书以相同的方式被拒绝。

The customer has sent me a screen shot of a no certificate returned from his logs and claims that this log entry means that I am passing the client certificate over the wire in a wrong format.

错了。它的意思正是它所说的。

没有 return 证书。当您没有 return 证书时,就会发生这种情况。反过来会发生这种情况,因为您的 SSL 软件找不到由服务器在 CertificateRequest 消息中指定的一种证书类型或受信任的签署者签署的证书。

这又意味着两件事之一:

  1. 您没有在密钥库中正确安装签名证书。执行此操作的步骤是 (1) 安装他们提供的根证书,使用 -trustcacerts 选项, 到密钥库, 和 (2) 安装签名证书 使用生成密钥对和 CSR 时使用的相同别名。

  1. 他们不信任自己的根证书,因此他们没有在 CertificateRequest 消息中将自己的根 CA 作为可信签署人发送,或者没有包含其类型。

我的钱都花在了 (1) 和 (2) 上,但是客户签署你的证书的整个业务是荒谬的。如果他的信任库无法识别公认的 CA,那就是他们要解决的问题,而不是更改为不同的签名者,这只会转移问题。例如,你信任他们的签名者吗?我的意思不仅是信任库意义上的,而且是公司安全意义上的?

如果是 (2),则表示客户的软件无法识别他自己颁发的证书,所以我完全不明白您为什么需要参与。

Any comments on the customer's claim about wrongly formatted client certificate being submitted?

我的意见是这不会激发信心。

I have found a place in Google where it is mentioned that the no certificate returned log entry can occur in cases where a client certificate is missing the Client Authentication extension.

换句话说,他们没有正确签名。

我对'the following TCP dump screen shot where a pkcs has been circled'也没有任何信心,除非上面有一个CertificateRequest然后一个Certificate消息。如果这一切都是真的,那么客户似乎颁发了错误的证书。

任何关于您损坏它的指控都可以忽略不计,因为它在两端都无法通过验证。同样,任何关于您的软件在传输过程中损坏它的指控也可以打折扣,因为您使用 Java 而不是您自己的代码来执行此操作。

所有这些只会更加强烈地表明您应该忘记客户签署证书并让他们解决 GeoTrust 根 CA 证书的原始问题。简单多了,又不涉及你