Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decrypt using an RSA public key with PyCrypto

As far as I understand, I should be able to use RSA to ensure authenticity or privacy, as I wish. In my case, I want to ensure authenticity so I encrypt the data with the private key and allow anyone to decrypt it with the public key. The data is not really secret but I need to guarantee that it was created by the owner of the public (and private) key.

When I try to decrypt using PyCrypto I get No private key error from PyCrypto. The code is this:

def _decrypt_rsa(decrypt_key_file, cipher_text):
    from Crypto.PublicKey import RSA
    from base64 import b64decode

    key = open(decrypt_key_file, "r").read()
    rsakey = RSA.importKey(key)
    raw_cipher_data = b64decode(cipher_text)
    decrypted = rsakey.decrypt(raw_cipher_data)
    return decrypted

I'm calling it with the path to the public key file (in OpenSSH format.) The encrypted data isn't generated by me and it was not done with Python but PHP. In PHP there's a openssl_public_decrypt function that decrypts this data easily.

Is it possible at all to decrypt using the public key with PyCrypto?

like image 749
sergiopereira Avatar asked Oct 23 '13 17:10

sergiopereira


People also ask

How to encrypt and decrypt data in Python using RSA?

Using the RSA module of PyCryptodome one can encrypt and decrypt data easily using Python. RSA uses public-key cryptography. Using RSA one can generate a key pair consisting of a private key and a public key. The private key needs to be kept secret while the public key can be shared with others.

What is RSA public-key cryptography?

"""RSA public-key cryptography algorithm (signature and encryption). RSA_ is the most widespread and used public key algorithm. Its security is based on the difficulty of factoring large integers. The algorithm has secure for new designs. authentication (digital signature).

How to import RSA key in ciphers?

We define the public key as parameter extern_key which is the RSA key to import. It will return an RSA key object key. The method PKCS1_OAEP.new () will accept the RSA key object as parameter key and return a cipher object of type PKCS1OAEP_Cipher that can be used to do the actual encryption or decryption of the data.

How to encrypt a message with a public key certificate?

This message will be encrypted with the public key certificate public_key.pem as per the RSA algorithm. Ideally, the public certificate should be publicly available and the private certificate should be kept private. The RSA.import_key () method will import the public key to be used to encrypt, from the certificate on disk.


1 Answers

That is totally insecure, because you are using raw RSA without padding.

Your application needs a signature, so you should not be dealing with encryptions and decryptions. For instance, PKCS#1 v1.5 is a good protocol, even though the signature is a piece of data that must be appended to what you want to prove the authenticity of.

To verify a PKCS#1 v1.5 signature in Python, you do:

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA

rsa_key = RSA.importKey(open(verification_key_file, "rb").read())
verifier = PKCS1_v1_5.new(rsa_key)
h = SHA.new(data_to_verify)
if verifier.verify(h, signature_received_with_the_data):
    print "OK"
else:
    print "Invalid"

I would strongly recommend to change the PHP code so that it creates such a signature.

like image 142
SquareRootOfTwentyThree Avatar answered Sep 22 '22 12:09

SquareRootOfTwentyThree