在python中从pkcs7提取签名数据 [英] extract signed data from pkcs7 in python
问题描述
我有一个USB加密令牌,能够签名数据并将其打包在pkcs文件中.然后我可以使用openssl从该文件中提取证书和数据,如下所示:
openssl cms -verify -in signature.p7s -inform DER -noverify -outform DER -signer cert.pem -out textdata
所以我的问题是如何使用python(pyopenssl)做同样的事情?
我已尝试按照此处所述进行操作,但是有不同的情况-我已经附加了签名,没有单独的签名和证书文件-我具有ASN.1编码的文件,其中包含作为数据和签名的证书
要实现您想要的目标,需要克服几个障碍.
首先,pyopenssl
绑定本身在其所需功能所在的crypto
模块上受到限制.实际上, pyopenssl crypto
文档指出:
提到的 pyca/cryptography
模块是通过pyopenssl crypto
模块的两个内部属性公开的,名称分别为_lib
和_ffi
,需要使用它们来获得所需的功能.
然后CMS_verify()
函数(这是您对此的逻辑选择)也不包含在pyca/cryptography
绑定中.但是,出于您的目的,使用PKCS7_verify()
可能足够好-您可以在StackExchange问题 OpenSSL中阅读有关此内容的全部信息. PKCS#7与S/MIME .函数 crypto.load_pkcs7_data()
派上用场. /p>
话虽如此,以下代码段可能会为您做到这一点-尽管从您的描述来看,我不清楚[c11>文件中是否包含签名者的证书(在这种情况下,您没有像您一样将-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))
如果您决定使用此方法,请有关使用此方法的警告直接使用OpenSSL绑定模块:
i have a usb cryptotoken and able to sign data and pack it in pkcs file. then i can extract certificate and data from that file using openssl as follows:
openssl cms -verify -in signature.p7s -inform DER -noverify -outform DER -signer cert.pem -out textdata
so my question is how to do the same using python (pyopenssl)?
i've tried to do as described here, but there is different case - i have attached signature and do not have separate signature and certificate file - i have ASN.1 encoded file, which contains as certificates as data and signature
There are several hurdles to overcome to achieve what you are looking for.
First, the pyopenssl
binding itself is limited when it comes to its crypto
module, where you desired functionality resides. In fact, the pyopenssl crypto
documentation states:
The pyca/cryptography
module mentioned is exposed via two internal attributes of the pyopenssl crypto
module, with the names _lib
and _ffi
, which need to be used to get to the required functionality.
Then the CMS_verify()
function that would be your logical choice for this is not included in the pyca/cryptography
bindings either. However, for your purpose it is probably good enough to use PKCS7_verify()
-- you can read all about that in a StackExchange question OpenSSL PKCS#7 vs. S/MIME. The function crypto.load_pkcs7_data()
comes in handy.
All that said, the following code snippet might do it for you -- although from your description it is not clear to me whether the certificate of the signer is included in the .p7s
file (in that case you do not have to give -signer
as an argument to openssl cms -verify
like you did). It worked for me, so give it a try:
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))
In case you decide to use this approach, here is a caveat about using this OpenSSL bindings module directly:
这篇关于在python中从pkcs7提取签名数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!