我正在开发一个利用API的Web应用程序。在响应中,API服务器会发送一个链接到一个X509证书(以PEM格式组成签名证书和一个或多个中间证书到根CA证书),我必须下载并使用它进行进一步的验证。
在使用证书之前,我需要确保证书链中的所有证书合并在一起创建了到受信任的根CA证书的信任链(以检测和避免任何恶意请求)。但我在Python中很难做到这一点,对于这个问题的研究也没有得到有用的结果。
使用requests和M2Crypto可以轻松地获取和加载证书。
import requests
from M2Crypto import RSA, X509
mypem = requests.get('https://server.com/my_certificate.pem')
cert = X509.load_cert_string(str(mypem.text), X509.FORMAT_PEM)
然而,验证证书链是一个问题。我不能将证书写入磁盘以使用类似于子进程的命令行实用程序(如openssl
),因此必须通过Python完成。我也没有任何打开的连接,因此使用基于连接的验证解决方案(如在此答案/线程中提到的:https://dev59.com/TXNA5IYBdhLWcg3wHp-B#1088224)也不起作用。
在关于此问题的另一个线程(https://dev59.com/l2855IYBdhLWcg3wViu3#4427081)中,abbot解释说m2crypto无法进行此验证,并说他编写了一个扩展来允许验证(使用模块m2ext
),但他的修补程序似乎从不起作用,即使我知道它是有效的:
from m2ext import SSL
ctx = SSL.Context()
ctx.load_verify_locations(capath='/etc/ssl/certs/') # I have run c_rehash in this directory to generate a list of cert files with signature based names
if not ctx.validate_certificate(cert): # always happens
print('Invalid certificate!')
此外,在类似的线程中,这里还有一个答案https://dev59.com/I03Sa4cB1Zd3GeqPsiSi#9007764,John Matthews声称他写了一个可以做到这一点的补丁,但不幸的是,该补丁链接现已失效--而且在那个线程中有一个评论说该补丁不能与openssl 0.9.8e一起使用。
所有与在Python中验证证书链信任相关的回答似乎要么链接到无效的补丁,要么返回到m2ext
。
是否有一种简单、直接的方法来验证我的证书链信任在Python中?