Simple Asymetric Encryption With Python
September 14, 2020
Python
Asymetric Encryption
So, first of all, this is just a snippet for those who courious and wants to know about asymetric encryption using private and public key to securing your data or communication. As we know, end to end encryption is very popular right now such as in your private messaging application (Whatsapp or Telegram), it is non deniable, one of our way to securing our communication in digital era.
The concept is very simmple, both parties are generating two kind of keys, one is private and one is public. the private key must be kept secret because this can be used for decrypting your encrypted data which are encrypted with your public key. So, in every communication you send your public key to everyone else, then, they are encrypting their sensitive data for you with your shared public key and become gibberish… the encrypted data then can be reversed to plain format with your secret key, thats it!
Below, simple PoC of above description with Python
and cryptography
library
-
Installing
cryptography
librarypip install cryptography
-
Generating keys (private and public)
#import necessary package import cryptography from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization # generating privae key private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) # generating public key public_key = private_key.public_key() # saving private and public key to file serial_private = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) with open("private_key.pem", "wb") as f: f.write(serial_private) serial_pub = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) with open("public_key.pem", "wb") as f: f.write(serial_pub)
Now, have two files of keys,
public_key.pem
andprivate_key.pm
-
Encrypting plain text with public key
# to encrypt plain text we need to open public key and hash text with this public key # imports import cryptography from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding key_file = open('public_key.pem', 'rb') # load public key public_key = serialization.load_pem_public_key( key_file.read(), backend = default_backend() ) # plain text plain_text = b"Only you can read this..." # must in bytes format # encrypting plain text encrypted = public_key.encrypt( plain_text, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) # write encrypted content to file with open("encrypted_content.txt", "wb") as f: f.write(encrypted)
there you go, now you have your message encrypted and stored into a file called
encrypted_content.txt
and if we try to read the contentcat encrypted_content.txt ------------------------- bx,ˆ˝2?ÉËæ˙êõ跥˰cŒ‰ ÉÒx&P>]§x|¥]‡¶'6%¬ë„á’'»≥=ùì4i‚8aöÒ‘3ë∞ ¯qîmm_€¥‘∏fRä‚Ñ™∏ùw¸Ñ#Õîg÷“:–g´åa9N[ôœÀöÂÆt∂ßj29¡±pD‚™v]$ˇfiF–≥ê ≤E}®^Ÿ‘è¿òsúq‡…°4Oçrî8]~õ¥ßN;”{˜Ÿbc9u!›ÃfÌ{≈KÎgΛ`∆aπ∑ùsF±I˜ç÷ÿ?ä∆¬÷&Öà“§ΩM∫‹LKwi⁄O¥$ˇπ“›ß?ïCLŒ“˙ŒÊÁE
you will have gibberish text, and yes it works!
-
Decrypting encrypted data to plain format with private key
Now, let say if someone give you an encrypted message which are encrypted with your own public key, supposed to be you are the only one who can reversed it back because you have the private key right? then how to reverse the encrypted message? you can follow this script below
# ... import packages same as above # load private key file key_file = open('private_key.pem', 'rb') private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) # open encrypted file encrypted_text = open("encrypted_content", "rb").read() # decrypt file plain_text = private_key.decrypt( encrypted_text, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print(plain_text) ## this should produce your plain non encrypted text #Only you can read this...
thats all, for your notes, this asymetric encryption has their own limits in encryption size, you can read them on library documentation.