Hi! Let’s encrypt some data using an RSA Public Key Certificate in Python. Let’s go! ✨⚡🔥
To understand what we’re doing here, please check out our two foundation tutorials on RSA Encryption:
Once you are up to speed, you can jump into the following code to encrypt data with an RSA Public Key, But first, ensure you install the pycryptodomex module:
pip install pycryptodomex
Then you write the following code:
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
##########################GENERATE CERTIFICATE PAIR########################
new_key = RSA.generate(2048)
private_key = new_key.exportKey("PEM")
public_key = new_key.publickey().exportKey("PEM")
fd = open("private_key.pem", "wb")
fd.write(private_key)
fd.close()
fd = open("public_key.pem", "wb")
fd.write(public_key)
fd.close()
################ENCRYPT/DECRYPT DATA WITH CERTIFICATE#######################
message = b'CODE EVERYDAY TO GET BETTER'
key = RSA.import_key(open('public_key.pem').read())
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(message)
print(ciphertext)
print("\n\n")
Let’s explain what is happening here:
- We do the usual imports to generate our RSA public/private certificate pair but this time we include an extra method PKCS1_OAEP which will be used to create the cipher object to encrypt our plaintext with the key that is in the certificate.
- We generate our public and private RSA certificates to disk as public_key.pem and private_key.pem respectively, as usual. These certificates contain our keys. Recall that a key is simply a string of text.
- We define the message to be encrypted in bytes as message. 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. 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. The return value is stored as cipher.
- The method cipher.encrypt() takes one parameter message and it will actually encrypt it using the key previously specified. It will return the encrypted plaintext message as ciphertext.
- We simply print the ciphertext to the screen. It will look like gibberish because it is encrypted.
If all goes well, the code above will produce two new files on disk in the same folder as the script: public_key.pem and private_key.pem. It will also print the following ciphertext to the screen:
#OUTPUT
""" b'\x1f\xc1F"\x83/k1!\xd6\'\xba\x1f/\xa1<=\xb0\x07\xb2\xb3q\xf5\nA\x81\x8f
\xf8r&\t\x95x\xa9;\xa8\xc2\xe5\xa2? \xe3\xc6\xb3\xcf\x9c\x123\x071\xe7<\x1d~\x86.
\xc4L\xa8\x82V\xc2sfO\x98\xa8\xdc\x8b\xc6\x7f\xf5M`]|\x89\xa3v\x13/7\x80\x94\x94
\xb1\x8c(\xaf\x9a\xd9\xbaf\xd9\xd1\xfb\xfe|/\x08\xe5-\xf5\xb7G\xbb\xdf\x13T\xf5\xd1
\x0b4\x05\x8e\x82\xfb\xf2\xd6\x11\xab\xf7\xa5nmGYz<z\x86\xf9N,\xa9\xaf#\x07\xa0\x1a
\xcd\x95\xa7\xaeG\xca\x8f\x7f\x88g\xdfP"\xb4\xf0\xa7\x01.\xc5\xa9s\x02\xd0\x15E\xd0
\xa2\xc2/\x98\xab\xe3\xae\xee-\xbdl\xa6\xbbA\x95\x88\x9f&\xba^\xd3tX\x815\xa2\xcbEA
\xc2\xfan\x11\xbdV\x00\xcf\x81\x06%y#LH\xbbja\xd5J\xe1\x91l\xe0B\x02\xf6\xa7)2KF\x0fMJ\xe1\xa9
\xcfB\xc7\xbbr\xe3\x94V\x07\x0f\x0c\x10/9\x03C%\xf5\x88\xe3\xe8x\x07M'
"""
OK! Of course, now we want to decrypt the message using our private key. Only someone who has access to the private key certificate that corresponds to the public key certificate used to encrypt the message, can decrypt it. This is our decryption code:
key = RSA.import_key(open('private_key.pem').read())
cipher = PKCS1_OAEP.new(key)
plaintext = cipher.decrypt(ciphertext)
print (plaintext.decode("utf-8"))
What we are doing here is simply the reverse of the encryption process. The difference is that we are importing the private key from the private certificate. Also, we are using the cipher.decrypt() method, to decrypt the ciphertext. When the above code executes the following plaintext will be printed to the screen:
#output
#CODE EVERYDAY TO GET BETTER
If all goes well, the plaintext should be exactly what the original message was. Below is our full code:
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
############G##############GENERATE CERTIFICATE PAIR########################
new_key = RSA.generate(2048)
private_key = new_key.exportKey("PEM")
public_key = new_key.publickey().exportKey("PEM")
fd = open("private_key.pem", "wb")
fd.write(private_key)
fd.close()
fd = open("public_key.pem", "wb")
fd.write(public_key)
fd.close()
################ENCRYPT/DECRYPT DATA WITH CERTIFICATE#######################
message = b'CODE EVERYDAY TO GET BETTER'
key = RSA.import_key(open('public_key.pem').read())
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(message)
print(ciphertext)
print("\n\n")
key = RSA.import_key(open('private_key.pem').read())
cipher = PKCS1_OAEP.new(key)
plaintext = cipher.decrypt(ciphertext)
print (plaintext.decode("utf-8"))
Thanks for reading! We hope this helped. Check out the PyCryptodomex documentation HERE. Check out our AES Encryption tutorial HERE.
Are you worried about your child’s online safety or your employees’ productivity? Do you wonder what they’re accessing on their devices? SentryPC is here to address these concerns. This all-in-one, cloud-based software provides robust activity monitoring, content filtering, and time management, making it ideal for both parental control and employee monitoring. Embrace peace of mind and enhanced efficiency with SentryPC, the proactive solution to your digital monitoring needs. CLICK HERE to get started.
Good luck! 👌👌👌