извлечь подписанные данные из pkcs7 в Python - PullRequest
0 голосов
/ 15 сентября 2018

У меня есть криптотокен USB и я могу подписать данные и упаковать их в файл pkcs. Затем я могу извлечь сертификат и данные из этого файла, используя openssl следующим образом:

openssl cms -verify -in signature.p7s -inform DER -noverify -outform DER -signer cert.pem -out textdata

так что мой вопрос, как сделать то же самое с помощью Python (pyopenssl)?

Я пытался сделать, как описано здесь , но есть другой случай - я прикрепил подпись и у меня нет отдельной подписи и файла сертификата - у меня есть файл в кодировке ASN.1, который содержит как сертификаты как данные и подпись

1 Ответ

0 голосов
/ 16 сентября 2018

Есть несколько препятствий для достижения того, что вы ищете.

Во-первых, сама привязка pyopenssl ограничена, когда речь идет о ее модуле crypto, в котором находятся нужные вам функции. Фактически, документация pyopenssl crypto гласит: enter image description here Упомянутый модуль pyca/cryptography предоставляется через два внутренних атрибута модуля pyopenssl crypto с именами _lib и _ffi, которые необходимо использовать для получения необходимой функциональности.

Тогда функция CMS_verify(), которая будет вашим логическим выбором для этого, также не включена в привязки pyca/cryptography. Однако для вашей цели, вероятно, достаточно использовать PKCS7_verify() - вы можете прочитать все об этом в вопросе StackExchange OpenSSL PKCS # 7 против 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)) 

В случае, если вы решите использовать этот подход, вот предостережение об использовании этого модуля привязок OpenSSL напрямую : enter image description here

...