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.
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
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With