我想确保客户端库(目前在 Python、Ruby、PHP、Java 和 .NET 中)配置正确,并在 SSL 证书无效时适本地失败。 Shmatikov 的论文,The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software ,揭示了 SSL 验证是多么令人困惑,所以我想彻底测试可能的失败。
根据研究,证书在以下情况下无效:
- 在激活日期之前使用
- 过期使用
- 已被撤销
- 证书主机名与站点主机名不匹配
- 证书链不包含受信任的证书颁发机构
理想情况下,我想每个无效案例都有一个测试用例。为此,我目前正在测试通过 HTTPS
访问的 HTTP
站点,这会导致失败,我可以在这样的测试中验证:
self.assertRaises(SSLHandshakeError, lambda: api.call_to_unmatched_hostname())
这是不完整的(只涵盖了一种情况)并且可能是错误的,所以......
您如何测试非浏览器软件是否正确验证 SSL 证书?
最佳答案
首先,您需要一组 SSL 证书,其中每个证书都有一个问题。您可以使用 openssl 命令行工具生成这些文件。当然,您不能使用受信任的根 CA 对它们进行签名。您将需要使用自己的 CA。要正确验证,您需要在客户端库中安装 CA 证书。您可以在 Java 中执行此操作,例如,使用控制面板。
获得证书后,您可以使用“openssl s_server”工具为使用每个证书的 SSL 套接字提供服务。我建议你在每个端口上放一个证书。
您现在必须使用客户端库连接到一个端口,并验证您是否收到了正确的错误消息。
我知道 Python 默认情况下不进行证书验证(查看 httplib.HTTPSConnection 的手册)。但是,m2crypto 确实会进行验证。默认情况下,Java 会进行验证。我不知道其他语言。
您可以测试的其他一些情况: 1) 通配符主机名。 2) 证书链接。我知道旧浏览器中有一个错误,如果你有一个由根签名的证书 A,A 可以签名 B,B 看起来有效。 SSL 应该通过在证书上设置标志来阻止这种情况,而 A 不会有“可以签名”标志。但是,这在某些旧浏览器中未得到验证。
祝你好运!我很想知道你的进展情况。
保罗
关于security - 您如何测试 SSL 客户端库是否正确验证了它所连接的服务器的证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17279683/