1
0
Fork 0
python-3-script-collection/src/educational_aes-256-cbc.py

111 lines
3.5 KiB
Python

#!/usr/bin/python3
INFORMATION = """\
A simple file encryption and decryption program using AES-256-CBC encryption.
Authors: ChatGPT, Larry Holst. License: Creative Commons Zero 1.0 Universal
This program allows the user to encrypt a file using AES-256-CBC encryption and
a randomly generated key and IV. The encrypted file is saved to disk along with
the key and IV, which can later be used to decrypt the file. The program also
allows the user to decrypt an encrypted file using the key and IV.
Note: This program is for educational purposes only and should not be used for
sensitive data without proper security measures.
"""
from base64 import b64encode, b64decode
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import os
def encrypt(plaintext, key, iv):
backend = default_backend()
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
encryptor = cipher.encryptor()
padder = padding.PKCS7(128).padder()
padded_plaintext = padder.update(plaintext) + padder.finalize()
ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize()
return b64encode(iv + ciphertext).decode("utf-8-sig")
def decrypt(ciphertext, key, iv):
backend = default_backend()
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
decryptor = cipher.decryptor()
decoded_ciphertext = b64decode(ciphertext)
ciphertext = decoded_ciphertext[16:]
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
unpadder = padding.PKCS7(128).unpadder()
unpadded_plaintext = unpadder.update(plaintext) + unpadder.finalize()
return unpadded_plaintext
if __name__ == "__main__":
print(
INFORMATION
+ """
1. Encrypt file
2. Decrypt file
Anything else: Exit
"""
)
while True:
try:
choice = input("choice > ")
except KeyboardInterrupt or EOFError:
raise SystemExit
if choice == "1":
try:
plaintext = open(
input("File path of file to encrypt: ").strip(), "rb"
).read()
except FileNotFoundError:
print("File not found.")
raise SystemExit
key = os.urandom(32)
iv = os.urandom(16)
print(f"Key/IV pair: {key.hex()}+{iv.hex()}")
ciphertext = encrypt(plaintext, key, iv)
open(
input(
"File path to save the encrypted ciphertext encoded in "
+ "Base64: "
).strip(),
"w",
encoding="utf-8-sig",
).write(ciphertext)
print("Encrypted successfully!")
elif choice == "2":
try:
ciphertext = open(
input("File path of file to decrypt: ").strip(),
"r",
encoding="utf-8-sig",
).read()
except FileNotFoundError:
print("File not found.")
raise SystemExit
key, iv = [
bytes.fromhex(x)
for x in input("Enter key/IV pair: ").strip().split("+")
]
plaintext = decrypt(ciphertext, key, iv)
open(
input("File path to save the decrypted ciphertext: ").strip(), "wb"
).write(plaintext)
print("Decrypted successfully!")
else:
break
print()