tkansara
tkansara

Reputation: 638

Migrating RSA signature generation from m2crypto to pycrypto

I am hoping you can help me out with my migration to PyCrypto from M2Crypto.

The content to encrypt is XML. I am loading the pk as follows:

M2Crypto:

sha = hashlib.sha1(xml)
rsa_private_key = M2Crypto.RSA.load_key_string(PRIVATE_KEY)
signature = rsa_private_key.private_encrypt(sha.digest(), M2Crypto.RSA.pkcs1_padding)

PyCrypto:

sha = hashlib.sha1(xml.encode('utf-8'))
rsa_private_key = RSA.importKey(PRIVATE_KEY)
rsa_private_key = PKCS1_OAEP.new(rsa_private_key)
signature = rsa_private_key.encrypt(sha.digest())

It is at this point that the signature value is different for both M2Crypto and Pycrypto. Can anyone please let me know what am I doing different in PyCrypto?

Upvotes: 0

Views: 554

Answers (1)

Artjom B.
Artjom B.

Reputation: 61892

It's different because:

  • the padding is randomized and
  • you're not actually using the same padding scheme.

pkcs1_padding usually means PKCS#1 v1.5 padding whereas OAEP is PKCS#1 v2 padding. You would need to use PKCS1_v1_5 in pycrypto.

Since the padding is randomized, you cannot compare the ciphertext of both. You need to encrypt in one and decrypt in the other to see if the same hash is produced.

sha = hashlib.sha1(xml.encode('utf-8'))
rsa_public_key = RSA.importKey(PUBLIC_KEY)
rsa_public_key = PKCS1_v1_5.new(rsa_public_key)
recovered_hash = rsa_public_key.decrypt(signature_from_m2)
print("success?", sha.digest() == recovered_hash)

Note that there are dedicated classes in PyCrypto for generating signatures and verifying them. M2Crypto has additional functions on the RSA object to create (sign) and verify signatures.

Upvotes: 1

Related Questions