我一直在尝试访问一个API,该API使用下面给出的python请求库使用SSL进行保护
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.
如果我的理解是正确的,这个证书可以与任何服务器一起使用,因为它们是用“*”作为域签名的。
我猜请求库正在严格匹配主机名验证,而不是正则表达式匹配。
所以我的问题是,这是请求库的一个bug,还是它的缩进方式?
当我使用下面给出的curl命令时,它工作得非常好。
curl https://path/to/url --cert cert.pem --key key.pem --cacert ca.pem
所以我有两种可能,要么curl库不执行主机名验证,要么它们使用正则表达式进行验证。
我哪里做错了?期待一个详细的答案
通配符的匹配方式在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默认情况下也会检查主机名,并且有一个与浏览器的操作基本兼容的实现。
至于卷曲:这取决于你使用的卷曲的版本。7.36应该没问题,但旧版本有flaws in the validation。
对于通配符在证书中的解释,没有真正的、经过批准的标准。无论它们匹配一个标签,还是多个标签,无论它们是否匹配IP(SAN扩展中的那些绝对不匹配),是否可以匹配标签的一部分(
prefix-*.example.com
),等等都没有很好的定义。我建议不要单独使用
*
,而只使用一个完整的标签(*.example.com
)。别把它用在IPs上,只要名字。相关问题 更多 >
编程相关推荐