bor*_*une 6 python openssl pem x509 pkcs#7
我有一个 USB 加密令牌,能够对数据进行签名并将其打包到 pkcs 文件中。然后我可以使用 openssl 从该文件中提取证书和数据,如下所示:
openssl cms -verify -in signature.p7s -inform DER -noverify -outform DER -signer cert.pem -out textdata
Run Code Online (Sandbox Code Playgroud)
所以我的问题是如何使用 python (pyopenssl) 做同样的事情?
我已尝试按照此处所述进行操作,但存在不同的情况-我附加了签名但没有单独的签名和证书文件-我有 ASN.1 编码文件,其中包含作为数据和签名的证书
要实现您的目标,需要克服几个障碍。
首先,pyopenssl绑定本身在涉及其crypto模块时受到限制,您需要的功能驻留在该模块中。事实上,该pyopenssl crypto文件规定:

pyca/cryptography提到
的模块通过模块的两个内部属性公开pyopenssl crypto,名称_lib和_ffi,需要使用它们来获得所需的功能。
那么CMS_verify()作为您的逻辑选择的函数也不包含在pyca/cryptography绑定中。但是,出于您的目的,使用它可能已经足够了PKCS7_verify()- 您可以在 StackExchange 问题OpenSSL PKCS#7 vs. S/MIME 中阅读所有相关内容。该功能crypto.load_pkcs7_data()派上用场。
综上所述,以下代码片段可能会为您完成——尽管根据您的描述,我不清楚签名者的证书是否包含在.p7s文件中(在这种情况下,您不必-signer作为参数提供给openssl cms -verify像你一样)。它对我有用,所以试一试:
from OpenSSL import crypto
from OpenSSL._util import (
ffi as _ffi,
lib as _lib,
)
# Or, alternatively:
# from cryptography.hazmat.bindings.openssl.binding import Binding
# _lib = Binding.lib
# _ffi = Binding.ffi
with open('message_der.p7s', 'rb') as f:
p7data = f.read()
p7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, p7data)
bio_out =crypto._new_mem_buf()
res = _lib.PKCS7_verify(p7._pkcs7, _ffi.NULL, _ffi.NULL, _ffi.NULL, bio_out, _lib.PKCS7_NOVERIFY)
if res == 1:
databytes = crypto._bio_to_string(bio_out)
print(databytes)
else:
errno = _lib.ERR_get_error()
errstrlib = _ffi.string(_lib.ERR_lib_error_string(errno))
errstrfunc = _ffi.string(_lib.ERR_func_error_string(errno))
errstrreason = _ffi.string(_lib.ERR_reason_error_string(errno))
Run Code Online (Sandbox Code Playgroud)
如果您决定使用这种方法,这里有一个关于直接使用这个 OpenSSL 绑定模块的警告:
