I am trying to generate a signature for a payload. My tech stack is in Python3.6, which provides library like cryptography or pycrypto. Problem is, I am unable to recreate the function private_encrypt
of M2Crypto in libraries like cryptography. The signature generated by M2Crypto is accepted by my peer end as valid signature, while the ones generated by either two libraries are discarded saying invalid signature.
I have created a minimal POC using python2.7 to make my case.
import base64
payload = b'This is the payload for which I wish to generate signature'
### Using library cryptography ###
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
with open("private_key", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
signature = private_key.sign(
payload,
padding=padding.PKCS1v15(),
algorithm=hashes.SHA1()
)
encoded_signature = base64.b16encode(signature)
print("Signature using cryptography - ", encoded_signature)
### Using library pycrypto ###
from Crypto.Signature import PKCS1_v1_5, PKCS1_PSS
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
key = RSA.importKey(open('private_key').read())
h = SHA.new(payload)
signer = PKCS1_v1_5.new(key)
signature = signer.sign(h)
encoded_signature = base64.b16encode(signature)
print("Signature using pycrypto - ", encoded_signature)
### Using M2Crypto ###
import hashlib
import M2Crypto
digest = hashlib.sha1(payload).hexdigest()
private_key = M2Crypto.RSA.load_key('./private_key')
# Encrypt digest using private key and encode in Hex (Base16)
encoded_signature = base64.b16encode(private_key.private_encrypt(
digest, M2Crypto.RSA.pkcs1_padding))
print("Signature using M2Crypto - ", encoded_signature)
The signatures created by cryptography
and Crypto
are same, and different from one generated by M2Crypto
. TIA.