4.11 GETTING AN UPGRADE
EXERCISE 4.11: GETTING AN UPGRADE
Help Alice and Bob out. Rewrite the RSA encryption/decryption program to use the
cryptography
module instead ofgmpy2
operations.
# ex4_11.py (way more secure than listing4_4.py)
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import padding
def rsa_encrypt(m: bytes, public_key: rsa.RSAPublicKey):
return public_key.encrypt(
=m,
plaintext=padding.OAEP(
padding=padding.MGF1(algorithm=hashes.SHA256()),
mgf=hashes.SHA256(),
algorithm=None,
label
),
)
def rsa_decrypt(c: bytes, private_key: rsa.RSAPrivateKey):
return private_key.decrypt(
=c,
ciphertext=padding.OAEP(
padding=padding.MGF1(algorithm=hashes.SHA256()),
mgf=hashes.SHA256(),
algorithm=None,
label
),
)
def main():
= None
public_key_file = None
private_key_file = None
public_key = None
private_key
while True:
print("RSA Crypto")
print("------------------")
print("\tPrivate key file: {}".format(private_key_file))
print("\tPublic key file: {}".format(public_key_file))
print("\t1. Encrypt Message")
print("\t2. Decrypt Message.")
print("\t3. Load public key file ")
print("\t4. Load private key file.")
print("\t5. Create and load new public and private key files.")
print("\t6. Quit.\n")
= input(">> ")
choice
if choice == "1":
if not public_key:
print("\nNo public key loaded\n")
else:
= input("\nPlaintext: ").encode()
message = rsa_encrypt(message, public_key)
ciphertext print("\nCiphertext (hexlified): {}\n".format(ciphertext.hex()))
elif choice == '2':
if not private_key:
print("\nNo private key loaded\n")
else:
= input("\nCiphertext (hexlified): ")
ciphertext_hex = bytes.fromhex(ciphertext_hex)
ciphertext = rsa_decrypt(ciphertext, private_key)
message print("\nPlaintext: {}\n".format(message))
elif choice == '3':
= input("\nEnter public key file: ")
public_key_temp_file if not os.path.exists(public_key_temp_file):
print(f"File {public_key_temp_file} does not exist.")
continue
with open(public_key_temp_file, 'rb') as f:
= serialization.load_pem_public_key(
public_key =f.read(),
data=default_backend()
backend
)= public_key_temp_file
public_key_file print("\nPublic Key file loaded.\n")
# unload private key if any
= None
private_key_file = None
private_key elif choice == '4':
= input("\nEnter private key file: ")
private_key_file_temp if not os.path.exists(private_key_file_temp):
print(f"File {private_key_file_temp} does not exist.")
continue
with open(private_key_file_temp, 'rb') as f:
= serialization.load_pem_private_key(
private_key =f.read(),
data=default_backend(),
backend=None
password
) = private_key_file_temp
private_key_file print("\nPrivate Key file loaded.\n")
# load public key for the given private key
# (unload previous public key if any)
= private_key.public_key()
public_key = None
public_key_file elif choice == '5':
= input("\nEnter a file name for new private key: ")
private_key_file_temp = input("\nEnter a file name for a new public key: ")
public_key_file_temp
if os.path.exists(private_key_file_temp) or os.path.exists(public_key_file_temp):
print("File already exists")
continue
with open(private_key_file_temp, "wb+") as private_key_file_obj:
with open(public_key_file_temp, "wb+") as public_key_file_obj:
= rsa.generate_private_key(
private_key =65537,
public_exponent=2048,
key_size=default_backend(),
backend
)= private_key.public_key()
public_key
private_key_file_obj.write(
private_key.private_bytes(=serialization.Encoding.PEM,
encodingformat=serialization.PrivateFormat.TraditionalOpenSSL,
=serialization.NoEncryption(),
encryption_algorithm
)
)
public_key_file_obj.write(
public_key.public_bytes(=serialization.Encoding.PEM,
encodingformat=serialization.PublicFormat.SubjectPublicKeyInfo,
)
)
= None
public_key_file = private_key_file_temp
private_key_file elif choice == '6':
print("\n\nTerminating. This program will self destruct in 5 seconds. \n")
break
else:
print("\n\nUnknown Option {}.\n".format(choice))
if __name__ == '__main__':
main()
Note that the UI of the previous code is identical to the UI of the code given in Exercise 4.1. Thus the following video still is correct for the above code.