我需要编写一个脚本,通过HTTPS连接到公司内部网上的一堆站点,并验证他们的SSL证书是否有效;他们没有过期,他们是为正确的地址等发出的 . 我们为这些网站使用我们自己的内部公司证书颁发机构,因此我们有CA的公钥来验证证书 .
默认情况下,Python在使用HTTPS时接受并使用SSL证书,因此即使证书无效,诸如urllib2和Twisted之类的Python库也会很乐意使用证书 .
是否有一个好的库可以让我通过HTTPS连接到一个站点并以这种方式验证它的证书?
如何在Python中验证证书?
10 回答
Jython默认情况下会执行证书验证,因此使用标准库模块,例如使用jython的httplib.HTTPSConnection等将验证证书并为失败提供例外,即不匹配的身份,过期的证书等 .
事实上,你必须做一些额外的工作才能使jython表现得像cpython,即让jython不验证证书 .
我写过一篇关于如何在jython上禁用证书检查的博客文章,因为它在测试阶段等方面很有用 .
在java和jython上安装一个完全信任的安全提供程序 .
http://jython.xhaus.com/installing-an-all-trusting-security-provider-on-java-and-jython/
pyOpenSSL是OpenSSL库的接口 . 它应该提供您需要的一切 .
我遇到了同样的问题但想要最小化第三方依赖(因为这个一次性脚本是由许多用户执行的) . 我的解决方案是包装
curl
调用并确保退出代码是0
. 工作就像一个魅力 .从发布版本2.7.9 / 3.4.3开始,Python by default 尝试执行证书验证 .
这已在PEP 467中提出,值得一读:https://www.python.org/dev/peps/pep-0476/
这些更改会影响所有相关的stdlib模块(urllib / urllib2,http,httplib) .
相关文件:
https://docs.python.org/2/library/httplib.html#httplib.HTTPSConnection
https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection
请注意,新的内置验证基于系统提供的证书数据库 . 与之相反,requests包附带了自己的证书包 . Trust database section of PEP 476讨论了这两种方法的优缺点 .
我已经在Python Package Index中添加了一个发行版,它使Python 3.2
ssl
包中的match_hostname()
函数可用于以前版本的Python .http://pypi.python.org/pypi/backports.ssl_match_hostname/
你可以安装它:
或者您可以将其作为项目的
setup.py
中列出的依赖项 . 无论哪种方式,它可以像这样使用:您可以使用Twisted来验证证书 . 主API是CertificateOptions,可以作为
contextFactory
参数提供给各种函数,例如listenSSL和startTLS .不幸的是,Python和Twisted都没有提供实际进行HTTPS验证所需的大量CA证书,也没有HTTPS验证逻辑 . 由于a limitation in PyOpenSSL,你还不能完全正确地完成它,但是由于几乎所有证书都包含一个主题commonName,你可以得到足够接近 .
以下是验证Twisted HTTPS客户端的简单示例实现,它忽略通配符和subjectAltName扩展,并使用大多数Ubuntu发行版中“ca-certificates”包中存在的证书颁发机构证书 . 尝试使用您最喜欢的有效和无效的证书网站:) .
PycURL做得很漂亮 .
以下是一个简短的例子 . 如果有些东西可疑,它会抛出一个
pycurl.error
,你会得到一个带有错误代码和人类可读消息的元组 .您可能希望配置更多选项,例如存储结果的位置等 . 但不需要使用非必需品来混淆示例 .
可能引发异常的示例:
我发现有用的一些链接是setopt和getinfo的libcurl-docs .
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html
这是一个演示证书验证的示例脚本:
或者通过使用requests库简化您的生活:
A few more words about its usage.
M2Crypto可以do the validation . 如果您愿意,也可以使用M2Crypto with Twisted . Chandler桌面客户端uses Twisted for networking and M2Crypto for SSL,包括证书验证 .
基于Glyphs注释,似乎M2Crypto默认情况下比默认使用pyOpenSSL做更好的证书验证,因为M2Crypto也会检查subjectAltName字段 .
我还发表了关于如何使用get the certificates Mozilla Firefox在Python中附带并使用Python SSL解决方案的博客 .