2 Way SSL - 客户端证书未发送至服务器

7
我有一个应用程序部署在force.com平台的salesforce上,我正在尝试为其配置双向SSL。
也就是说,我希望每个从SF发送到我的服务器的请求都会发送一个客户端证书。
我已经在SF上进行了必要的配置以发送证书,但仍然从服务器获得403.7,这意味着:被禁止,需要客户端证书。
我在服务器上安装了Wireshark,捕获流量以查看双向SSL握手,并试图在服务器hello消息中找到告诉客户端证书应该对应哪些受信任CA的位置,但我很难找到。
我怀疑这就是客户端未发送证书的原因。
有人能指导我在服务器hello消息中应该查找的位置吗?或者在另一个数据包捕获中?
先谢谢了。

enter image description here

客户端密钥交换记录:

enter image description here


寻找来自服务器的证书请求消息。如果没有,客户端将不会发送任何证书。另请参阅https://devcentral.f5.com/articles/ssl-profiles-part-8-client-authentication。 - Steffen Ullrich
添加了一个握手捕获的截图。 请问您能指出我应该看哪里吗? - Y.S
3个回答

8
在这里,服务器发送其 Certificate Request 消息,并且客户端响应时发送其 Certificate 消息,但该消息不包含任何证书。

通常,当客户端无法选择要使用的客户端证书时,就会发生这种情况。要么它没有正确配置以利用任何证书,要么它找不到由可接受的 CA 之一颁发的证书。
查看 Certificate Request 数据包并检查其 certificate_authorities 列表。这是服务器愿意接受的 CA Distinguished Names(DN)列表。
无论如何,客户端都需要找到一个客户端证书,以便可以构建一条链向这些 DN。在最简单的情况下,可以使用由此类 DN 颁发的客户端证书。否则,客户端可能需要从客户端证书到此类 DN 构建链路,它需要具备必要的中间 CA 证书才能这样做。(如何完成这项工作取决于客户端的配置机制。)
如果需要中间 CA 证书而客户端上没有可用的,您可能需要配置服务器以接受它们,并在 Certificate Request 中进行广告宣传。

如果服务器在其“证书请求”中不包括“证书颁发机构”列表怎么办?我在使用Amazon AWS IoT时遇到了麻烦。他们甚至没有发布任何客户端证书签名的CA或中间证书。 - Jan Schatz
我们遇到了同样的问题。正如上面所提到的,证书长度为零。 有办法强制将客户端证书发送到服务器吗? - osman katib
这个证书请求只在双向 SSL 中发送吗?还是在单向 SSL 中也会发送?谢谢。 - Diego Ramos

7

已添加握手捕获的截图,请问应该在哪里查看?

请查看第31个数据包,其中包含证书请求。另外第33个数据包包含客户端的证书,因此问题不是客户端未发送证书,而是服务器不喜欢该证书,可能是由于验证失败或证书不足以作为所请求资源的授权。您可以从服务器日志中获取更多信息。


2
请查看我添加的附加屏幕截图,涉及客户端密钥交换。它显示证书长度为0,因此我认为这应该是证书消息,但其中没有包含证书。我错了吗? - Y.S
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Y.S
@Y.S,你能告诉我你是如何解决这个问题的吗? 我也遇到了同样的问题。我正在使用 pem 格式的自签名证书和 openSSL,但是我得到了以下错误。 SSL_CTX_use_certificate_file 失败 [0,error:0906D06C:PEM routines:PEM_read_bio:no start line] - scooby
@scooby:你的问题与此无关。如果需要帮助,请提出新问题。提示:您的证书文件格式不符合预期。 - Steffen Ullrich

1
我不确定这是否会帮助其他人,但对于我们的情况,当在Visual Studio和IIS中本地运行时,一切正常,但当部署到真实服务器时,在进行双向SSL期间遇到了证书问题,如上所述并在Wireshark中验证。
无论如何,在该服务器上,我们还有一个.NET 4.7.2控制台应用程序,该应用程序调用相同的API,一切正常。
但是,我们的.NET 4.7.2 Web API调用失败了。看起来当相同的代码在IIS内运行时,证书在SSL协商过程中不可用(尽管它已经成功加载)。
此时,我们的解决方案是修改以下调用以包括第三个参数。
certificate = new X509Certificate2(certificatepath, Password, X509KeyStorageFlags.MachineKeySet);
默认情况下,X509Certificate2使用UserKeySet选项,因此可能应用程序池用户或IIS中的另一个线程无法访问协商的证书。
以下是我在研究过程中发现有用的几个相关页面:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接