如何验证 pyOpenSSL 中的证书签名?
How to verify certificate signature in pyOpenSSL?
我有两个证书,一个 root.crt
用于签署 client.crt
。
我想验证 client.crt
确实是由 root.key
签名的。
在终端上使用 openssl,它是这样工作的:
$ openssl verify -CAfile root.crt client.crt
> client.crt: OK
但是使用 pyOpenSSL - 在 documentation and this 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, 'unable to get issuer certificate']
我错过了什么?
问题是我的 root.crt
不是真正的 root,而是证书链:
-----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):
# returns a list of certificates
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 cert in parse_chain(file('root.crt').read()):
store.add_cert(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()
改编自https://github.com/hynek/pem/blob/master/src/pem/_core.py#L115
我有两个证书,一个 root.crt
用于签署 client.crt
。
我想验证 client.crt
确实是由 root.key
签名的。
在终端上使用 openssl,它是这样工作的:
$ openssl verify -CAfile root.crt client.crt
> client.crt: OK
但是使用 pyOpenSSL - 在 documentation and this 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, 'unable to get issuer certificate']
我错过了什么?
问题是我的 root.crt
不是真正的 root,而是证书链:
-----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):
# returns a list of certificates
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 cert in parse_chain(file('root.crt').read()):
store.add_cert(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()
改编自https://github.com/hynek/pem/blob/master/src/pem/_core.py#L115