извлечение подписанных данных из 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 напрямую :

