Skip to content

Instantly share code, notes, and snippets.

@PageotD
Last active August 14, 2024 05:57
Show Gist options
  • Save PageotD/0d49cd2b2947b6cd17d31b059ce7deb6 to your computer and use it in GitHub Desktop.
Save PageotD/0d49cd2b2947b6cd17d31b059ce7deb6 to your computer and use it in GitHub Desktop.
simple file encryption/decrytion in python
import argparse
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
import os
# Constants
SALT_SIZE = 16
IV_SIZE = 16
KEY_SIZE = 32
ITERATIONS = 100000
def derive_key(passphrase: str, salt: bytes) -> bytes:
"""Derives a key from the passphrase and salt."""
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=KEY_SIZE,
salt=salt,
iterations=ITERATIONS,
backend=default_backend()
)
return kdf.derive(passphrase.encode())
def encrypt_data(passphrase: str, data: str) -> bytes:
"""Encrypts data using AES encryption."""
salt = os.urandom(SALT_SIZE)
key = derive_key(passphrase, salt)
iv = os.urandom(IV_SIZE)
cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend())
encryptor = cipher.encryptor()
data_bytes = data.encode()
padding_length = (16 - len(data_bytes) % 16) % 16
padded_data = data_bytes + bytes([padding_length] * padding_length)
encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
return salt + iv + encrypted_data
def decrypt_data(passphrase: str, encrypted_data: bytes) -> str:
"""Decrypts data using AES encryption."""
salt = encrypted_data[:SALT_SIZE]
iv = encrypted_data[SALT_SIZE:SALT_SIZE+IV_SIZE]
encrypted_data = encrypted_data[SALT_SIZE+IV_SIZE:]
key = derive_key(passphrase, salt)
cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend())
decryptor = cipher.decryptor()
decrypted_data = decryptor.update(encrypted_data) + decryptor.finalize()
padding_length = decrypted_data[-1]
return decrypted_data[:-padding_length].decode()
def save_encrypted_file(filepath: str, passphrase: str, data: str):
"""Encrypts data and saves it to a file."""
encrypted_data = encrypt_data(passphrase, data)
with open(filepath, 'wb') as file:
file.write(encrypted_data)
def load_decrypted_file(filepath: str, passphrase: str) -> str:
"""Loads and decrypts data from a file."""
with open(filepath, 'rb') as file:
encrypted_data = file.read()
return decrypt_data(passphrase, encrypted_data)
def change_passphrase(filepath: str, old_passphrase: str, new_passphrase: str):
"""Change the passphrase for an encrypted file."""
# Load and decrypt the data with the old passphrase
decrypted_data = load_decrypted_file(filepath, old_passphrase)
# Encrypt the data with the new passphrase
save_encrypted_file(filepath, new_passphrase, decrypted_data)
def main():
parser = argparse.ArgumentParser(description="Encrypt, decrypt, or change passphrase of files.")
subparsers = parser.add_subparsers(dest='command')
# Encrypt command
encrypt_parser = subparsers.add_parser('encrypt', help='Encrypt a file')
encrypt_parser.add_argument('filepath', help='Path to the file to encrypt')
# Decrypt command
decrypt_parser = subparsers.add_parser('decrypt', help='Decrypt a file')
decrypt_parser.add_argument('filepath', help='Path to the file to decrypt')
# Change passphrase command
change_passphrase_parser = subparsers.add_parser('changepass', help='Change the passphrase of a file')
change_passphrase_parser.add_argument('filepath', help='Path to the file to update')
change_passphrase_parser.add_argument('old_passphrase', help='Current passphrase')
change_passphrase_parser.add_argument('new_passphrase', help='New passphrase')
args = parser.parse_args()
if args.command == 'encrypt':
passphrase = input("Enter passphrase: ")
with open(args.filepath, 'r') as file:
data = file.read()
save_encrypted_file(args.filepath + '.enc', passphrase, data)
print(f"File encrypted and saved as {args.filepath}.enc")
elif args.command == 'decrypt':
passphrase = input("Enter passphrase: ")
decrypted_data = load_decrypted_file(args.filepath, passphrase)
with open(args.filepath + '.dec', 'w') as file:
file.write(decrypted_data)
print(f"File decrypted and saved as {args.filepath}.dec")
elif args.command == 'changepass':
change_passphrase(args.filepath, args.old_passphrase, args.new_passphrase)
print(f"Passphrase changed for {args.filepath}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment