Non-detached PKCS#7 SHA1+RSA signature without M2Crypto

这一生的挚爱 提交于 2019-12-28 04:26:06

问题


I'm trying to create a non-detached signature on python3. I currently have code that does this on python2 with m2crypto, but m2crypto isn't available for python3.

I've been trying rsa, pycrypto and openssl, but haven't seen to find how.

Here's the equivalent OpenSSL command:

openssl smime -sign -signer $CRTFILE -inkey $KEYFILE -outformDER -nodetach

It's the nodetach option that I can't imitate with either rsa, pyopenssl or pycrypto.

Has anyone does this on python3? I'd like to avoid using Popen+openssl as much as possible.


回答1:


It looks like you can achieve this with pyca/cryptography if you do not mind doing some lower-level OpenSSL programming. You can give this a try:

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.bindings.openssl.binding import Binding

_lib = Binding.lib
_ffi = Binding.ffi

msg = "Hello, World!"

with open('key.pem', 'rb') as key_file:
    private_key = serialization.load_pem_private_key(
        key_file.read(), None, default_backend())

with open('cert.pem', 'rb') as cert_file:
    cert = x509.load_pem_x509_certificate(
        cert_file.read(), default_backend())

bio_in = _lib.BIO_new_mem_buf(msg.encode('utf-8'), len(msg))
pkcs7 = _lib.PKCS7_sign(cert._x509, private_key._evp_pkey, _ffi.NULL, bio_in, 0)

bio_out=_lib.BIO_new(_lib.BIO_s_mem())
_lib.PEM_write_bio_PKCS7(bio_out, pkcs7)

result_buffer = _ffi.new('char**')
buffer_length = _lib.BIO_get_mem_data(bio_out, result_buffer)
sout = _ffi.buffer(result_buffer[0], buffer_length)[:]

print(sout.decode('utf-8'))

This script is for illustration purposes only and there might be better ways to do it. This approach basically mimics your openssl smime command.

If you do want to go down this path, you will have to look closer at memory management and free up things when you are done. There is a reason why this stuff is called hazmat...




回答2:


I actually ended up solving this with OpenSSL.crypto, albeit, with some internal methods:

from OpenSSL import crypto

PKCS7_NOSIGS = 0x4  # defined in pkcs7.h


def create_embeded_pkcs7_signature(data, cert, key):
    """
    Creates an embeded ("nodetached") pkcs7 signature.

    This is equivalent to the output of::

        openssl smime -sign -signer cert -inkey key -outform DER -nodetach < data

    :type data: bytes
    :type cert: str
    :type key: str
    """  # noqa: E501

    assert isinstance(data, bytes)
    assert isinstance(cert, str)

    try:
        pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key)
        signcert = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
    except crypto.Error as e:
        raise ValueError('Certificates files are invalid') from e

    bio_in = crypto._new_mem_buf(data)
    pkcs7 = crypto._lib.PKCS7_sign(
        signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS
    )
    bio_out = crypto._new_mem_buf()
    crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7)
    signed_data = crypto._bio_to_string(bio_out)

    return signed_data


来源:https://stackoverflow.com/questions/32020356/non-detached-pkcs7-sha1rsa-signature-without-m2crypto

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!