如何使用Python验证具有证书颁发机构的公钥?

bad*_*eas 6 python ssl openssl public-key-encryption x509

import OpenSSL

key = ...
signature = ...
data = ...

x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, key)
OpenSSL.crypto.verify(x509, signature, data, 'sha1')
Run Code Online (Sandbox Code Playgroud)

到目前为止,我能够毫无问题地完成所有这些工作.但是,它并不觉得这是足够的安全性,因为密钥本身是通过URL(我应该信任*)给我的,并且构建签名的方法是公开可用的.

因此,据说密钥被"VeriSign Class 3 Code Signing 2010 CA"验证,有人能告诉我如何检查这是一个有效的声明吗?

我猜我需要在我的机器上本地获得VeriSign证书.假设我这样做,我从那里去哪里?

谢谢!

*URL作为JSON请求中的参数提供给我.当然,URL将是HTTPS,我可以检查域名和所有这些.但似乎我应该对证书本身进行检查

ran*_*om8 2

你是对的,你应该检查证书本身。是的,您需要签署要检查的证书的 VeriSign 根证书(以及具有完整信任链的任何其他中间证书)。

当前的 Symantec (VeriSign) 根证书可以在zipfile中找到。

下载并解压缩 zip 文件,找到您希望信任的所有证书,并将它们放在一起(以 pem 格式)到一个证书捆绑文件中。

现在您需要进行实际验证。不幸的是,您需要的 OpenSSL 调用是X509_verify_certificate. 我查看了 pyopenssl 和 M2Crypto 的源代码,但都没有公开该调用,因此您没有可以调用的直接 Python 代码来验证这两个包的证书。

但是,由于您使用的是 pyopenssl,因此显然您拥有可用的 openssl 库。因此,您可能已经拥有或可以轻松安装 openssl 命令行工具集。如果是这样,您可以通过管道调用 opensslverify命令,方法如下:

cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, key)
# the command like likes pem format
cert_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)

# the bundle that you created from the zip extraction
certificate_bundle = 'verisign-root-bundle.pem'

# Pipe the cert to the openssl verify command and check the return code
# a return code of 0 is successful verify
import subprocess
p = subprocess.Popen(['openssl', 'verify', '-CAfile', certificate_bundle],
                     stdin=subprocess.PIPE)
p.communicate(input=cert_pem)
p.wait()
if (p.returncode == 0):
    print('Certificate Verified.')
else:
    print('Problem with certificate')
Run Code Online (Sandbox Code Playgroud)

上面的管道运行命令

openssl verify -CAfile ca.bundle certificate.pem
Run Code Online (Sandbox Code Playgroud)

最后,如果您不熟悉 openssl,显示证书的命令是

openssl x509 -inform PEM -text -in certificate.pem
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!