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

前端 未结 2 969
别那么骄傲
别那么骄傲 2020-12-03 23:27

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.

相关标签:
2条回答
  • 2020-12-03 23:48

    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...

    0 讨论(0)
  • 2020-12-04 00:04

    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
    
    0 讨论(0)
提交回复
热议问题