извлечение подписанных данных из pkcs7 в python
У меня есть USB cryptotoken и возможность подписывать данные и упаковывать их в файл pkcs. затем я могу извлечь сертификат и данные из этого файла с помощью openssl следующим образом:
openssl cms -verify -in signature.p7s -inform DER -noverify -outform DER -signer cert.pem -out textdata
Итак, мой вопрос заключается в том, как сделать то же самое с помощью python (pyopenssl)?
Я попытался сделать так, как описано здесь, но есть другой случай - у меня есть прикрепленная подпись и нет отдельного файла подписи и сертификата - у меня есть ASN.1 закодированный файл, содержащий в качестве сертификатов данные и подпись
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()
пригодится.Все сказанное, следующий фрагмент кода может сделать это для вас - хотя из вашего описания мне не ясно, является ли сертификат подписывающего лица включен в файл
.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 напрямую :