pyOpenSSL" openssl verify -CAfile root.crt client.crt"当量

时间:2017-10-03 20:59:30

标签: python pyopenssl

我有两个证书,root.crtclient.crtroot.key签署。
我想验证client.crt确实是由root.key签名,为了这样做,在终端上使用openssl,我喜欢这样:

$ openssl verify -CAfile root.crt client.crt  
> client.crt: OK  

但是当使用pyOpenSSL时,在documentationthis blog post之后,我尝试了这样的事情:

client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('client.crt').read())

root_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('root.crt').read())  

store = OpenSSL.crypto.X509Store()  
store.add_cert(root_cert)  

ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()  

但后来我收到了这个错误:

  

X509StoreContextError:[2,1,'无法获得颁发者证书']

那么我错过了什么?

1 个答案:

答案 0 :(得分:2)

问题是我的root.crt不是真正的根,而是一系列证书:

-----BEGIN CERTIFICATE----- 
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- 
...
-----END CERTIFICATE-----

OpenSSL.crypto.load_certificate只会加载第一个。

解决方案是提取链文件中的所有证书并将其添加到X509Store

所以代码解决方案看起来像这样:

_PEM_RE = re.compile(b'-----BEGIN CERTIFICATE-----\r?.+?\r?-----END CERTIFICATE-----\r?\n?', re.DOTALL)


def parse_chain(chain):
    return [c.group() for c in _PEM_RE.finditer(chain)]


client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('server.crt').read())

store = OpenSSL.crypto.X509Store()
for rc in parse_chain(file('root.crt').read()):
    store.add_cert(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cr))

ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()

改编自https://github.com/hynek/pem/blob/master/src/pem/_core.py#L115