111 lines
3.5 KiB
Python
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()
|