smh*_*way 7 security testing ssl integration-testing
我想确保在SSL证书无效时正确配置客户端库(当前使用Python,Ruby,PHP,Java和.NET)并且失败.Shmatikov的论文,世界上最危险的代码:在非浏览器软件中验证SSL证书,揭示了SSL验证的混乱程度,因此我想彻底测试可能的失败.
根据研究,证书无效,如果:
理想情况下,我认为每个无效案例都会有一个测试用例.为此,我目前正在测试HTTP
访问过的网站HTTPS
,这导致我可以在测试中验证失败,如下所示:
self.assertRaises(SSLHandshakeError, lambda: api.call_to_unmatched_hostname())
Run Code Online (Sandbox Code Playgroud)
这是不完整的(仅涵盖一个案例)并且可能是错误的,所以...
如何测试非浏览器软件是否正确验证了SSL证书?
首先,您需要一组SSL证书,其中每个证书只有一个错误.您可以使用openssl命令行工具生成这些内容.当然,您无法使用受信任的根CA对其进行签名.您将需要使用自己的CA. 要正确验证,您需要在客户端库中安装CA证书.您可以在Java中执行此操作,例如,使用控制面板.
获得证书后,可以使用"openssl s_server"工具使用每个证书来提供SSL套接字.我建议你在每个端口上放一个证书.
您现在必须使用客户端库连接到端口,并验证您是否收到了正确的错误消息.
我知道默认情况下Python没有证书验证(查看httplib.HTTPSConnection的手册).但是,m2crypto会进行验证.默认情况下,Java会进行验证.我不了解其他语言.
您可以测试的其他一些案例:1)通配符主机名.2)证书链接.我知道旧浏览器中存在一个错误,如果你有一个由根签名的证书A,A可以签署B,B看起来有效.SSL应该通过在证书上放置标志来阻止这种情况,并且A不会有"can sign"标志.但是,在某些旧浏览器中未对此进行验证.
祝好运!我很想知道你是怎么过的.
保罗
证书主机名与站点主机名不匹配
这可能是最容易检查的,并且失败(失败)肯定有充分的迹象表明出了点问题。大多数知名服务的证书仅使用主机名作为其身份,而不使用IP地址。如果(而不是)https://www.google.com/
您要求https://173.194.67.99/
(例如)并且它有效,则说明存在问题。
对于其他的,您可能想要生成自己的测试CA。
证书链不包含受信任的证书颁发机构
您可以使用测试CA(或自签名证书)来生成测试证书,但可以使用默认的系统CA列表进行验证。您的测试客户端应该无法验证该证书。
它在激活日期之前使用,它的有效期后使用
您可以使用测试CA生成带有非之前/非之后日期的测试证书,该日期使当前日期无效。然后,将您的测试CA用作受信任的CA进行验证:由于日期,您的测试客户端应该无法验证证书。
它已被撤销
这可能是最难设置的,具体取决于撤销的发布方式。同样,使用您自己的测试CA生成一些您立即撤销的测试证书。某些工具期望在一组受信任的CA旁边配置一组CRL文件。这需要为测试本身进行一些设置,但是很少需要在线设置:这可能是最简单的。您也可以使用CRL分发点或OCSP来设置本地在线撤销存储库。
PKI测试可能比一般的测试更为复杂。完整的测试套件将需要对规范(RFC 5280)有很好的理解。确实,您可能需要检查所有中间证书的日期,以及链中每个证书的各种属性(例如,密钥用法,基本约束等)。
通常,客户端库将验证过程分为两个操作:验证证书是否受信任(PKI部分)和验证证书是否已颁发给您要连接的实体(主机名验证部分)。当然,这是由于在不同的文档(分别为RFC 3280/5280和RFC 2818/6125)中指定了这些事实。
从实际的角度来看,使用SSL库时要检查的前两点是:
在两种情况下均应发生连接/验证失败。如果所有方法都能正常工作,而没有实施完整的PKI测试套件(需要一定的专业知识),那么通常需要检查该SSL库的文档以查看如何启用这些验证。
除了错误,本文中提到的许多问题都归因于以下事实:某些库实现已做出假设,即取决于用户是否知道自己在做什么,而大多数用户似乎都做出了假设默认情况下,库在做正确的事情。(实际上,即使默认情况下该库执行正确的操作,也确实不乏程序员想要摆脱错误消息的程序员,即使这会使他们的应用程序不安全。)我似乎可以这样说在大多数情况下,确保启用验证功能就足够了。
至于一些现有实现的状态:
Python:Python 2.x和Python 3.x之间有所不同。ssl
Python 3.2 的模块具有match_hostname
Python 2.7没有的方法。urllib.request.urlopen
在Python 3.2中,还提供了一个配置CA文件的选项,而它的Python 2.7同等版本中没有。(也就是说,如果未设置,则不会进行验证。我不确定主机名验证。)
Java:默认情况下,对于的PKI和主机名HttpsUrlConnection
,验证均处于启用状态,而SSLSocket
直接使用时,主机名则不进行验证,除非您使用的是Java 7并且已配置了它的SSLParameters
使用setEndpointIdentificationAlgorithm("HTTPS")
(例如)。
PHP:据我所知,fopen("https://.../")
根本不会执行任何验证。
归档时间: |
|
查看次数: |
3066 次 |
最近记录: |