我一直在尝试使用python请求库来访问使用SSL保护的API,如下所示
requests.get('https://path/to/url',cert=('cert.pem','key.pem'),verify='ca.pem')
但是收到错误
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 385, in send
raise SSLError(e)
requests.exceptions.SSLError: hostname '10.10.10.10' doesn't match u'*' # IP address is not real.
如果我的理解是正确的,这个证书可以用于任何服务器,因为它们以'*'作为域签名。
我猜请求库正在严格匹配主机名验证而不是正则表达式匹配。
所以我的问题是它是否是请求库的错误,或者这是缩进工作的方式?
当我使用下面给出的curl命令时,它工作正常。
curl https://path/to/url --cert cert.pem --key key.pem --cacert ca.pem
所以我有两种可能性,卷曲库不执行主机名验证,或者他们正在使用正则表达式。
我在哪里错了?期待详细的答案
答案 0 :(得分:2)
RFC 2818中描述了如何匹配通配符,RFC 6125中更准确地说明了这些通配符,CAB baseline requirements中也有信息。最后,浏览器实现以下内容:
*
,*.*.example.com
等通配符。 *.example.com
匹配www.example.com
但不匹配sub.www.example.com
或example.com
。*.com
使用通配符,有些不允许*.co.uk
使用通配符。像python这样的几种语言过去根本没有对主机名进行任何检查,但2.7.9 python默认情况下也会检查主机名,并且其实现与浏览器的内容大致兼容。
至于curl:它取决于你使用的卷曲版本。 7.36应该没问题,但旧版本有flaws in the validation。
答案 1 :(得分:0)
没有关于如何在证书中解释通配符的真实,批准的标准。无论它们是匹配一个标签还是多个标签,它们是否匹配ips(SAN扩展中的标签肯定不是),是否可以匹配标签的一部分(prefix-*.example.com
)等都不是很好定义
我建议不要在其上使用*
,而只能使用一个完整标签(*.example.com
)。并且不要将它用于IP,只是名称。