Skip to content

Instantly share code, notes, and snippets.

@hotpotcookie
Forked from dustindorroh/python_rsa_example.py
Last active December 3, 2023 10:54
Show Gist options
  • Save hotpotcookie/1ad09de58c28789bba8a88cbb60d6ca5 to your computer and use it in GitHub Desktop.
Save hotpotcookie/1ad09de58c28789bba8a88cbb60d6ca5 to your computer and use it in GitHub Desktop.
RSA Encryption/Decryption with python
# Inspired from https://medium.com/@ismailakkila/black-hat-python-encrypt-and-decrypt-with-rsa-cryptography-bd6df84d65bc
# Updated to use python3 bytes and pathlib
import zlib
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from pathlib import Path
def generate_new_key_pair():
#Generate a public/ private key pair using 4096 bits key length (512 bytes)
new_key = RSA.generate(4096, e=65537)
#The private key in PEM format
private_key = new_key.exportKey("PEM")
#The public key in PEM Format
public_key = new_key.publickey().exportKey("PEM")
private_key_path = Path('private.pem')
private_key_path.touch(mode=0o600)
private_key_path.write_bytes(private_key)
public_key_path = Path('public.pem')
public_key_path.touch(mode=0o664)
public_key_path.write_bytes(public_key)
#Our Encryption Function
def encrypt_blob(blob, public_key):
#Import the Public Key and use for encryption using PKCS1_OAEP
rsa_key = RSA.importKey(public_key)
rsa_key = PKCS1_OAEP.new(rsa_key)
#compress the data first
blob = zlib.compress(blob)
#In determining the chunk size, determine the private key length used in bytes
#and subtract 42 bytes (when using PKCS1_OAEP). The data will be in encrypted
#in chunks
chunk_size = 470
offset = 0
end_loop = False
encrypted = bytearray()
while not end_loop:
#The chunk
chunk = blob[offset:offset + chunk_size]
#If the data chunk is less then the chunk size, then we need to add
#padding with " ". This indicates the we reached the end of the file
#so we end loop here
if len(chunk) % chunk_size != 0:
end_loop = True
#chunk += b" " * (chunk_size - len(chunk))
chunk += bytes(chunk_size - len(chunk))
#Append the encrypted chunk to the overall encrypted file
encrypted += rsa_key.encrypt(chunk)
#Increase the offset by chunk size
offset += chunk_size
#Base 64 encode the encrypted file
return base64.b64encode(encrypted)
#Our Decryption Function
def decrypt_blob(encrypted_blob, private_key):
#Import the Private Key and use for decryption using PKCS1_OAEP
rsakey = RSA.importKey(private_key)
rsakey = PKCS1_OAEP.new(rsakey)
#Base 64 decode the data
encrypted_blob = base64.b64decode(encrypted_blob)
#In determining the chunk size, determine the private key length used in bytes.
#The data will be in decrypted in chunks
chunk_size = 512
offset = 0
decrypted = bytearray()
#keep loop going as long as we have chunks to decrypt
while offset < len(encrypted_blob):
#The chunk
chunk = encrypted_blob[offset: offset + chunk_size]
#Append the decrypted chunk to the overall decrypted file
decrypted += rsakey.decrypt(chunk)
#Increase the offset by chunk size
offset += chunk_size
#return the decompressed decrypted data
return zlib.decompress(decrypted)
# generate_new_key_pair() # run if you don't already have a key pair
private_key = Path('private.pem')
public_key = Path('public.pem')
unencrypted_file = Path('deadbeef.txt')
encrypted_file = unencrypted_file.with_suffix('.dat')
encrypted_msg = encrypt_blob(unencrypted_file.read_bytes(), public_key.read_bytes())
decrypted_msg = decrypt_blob(encrypted_msg, private_key.read_bytes())
print('destination file : '+str(encrypted_file))
print('\ncipher message :\n'+str(encrypted_msg))
print('\nplain message :\n'+str(decrypted_msg))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment