From a458115f9696db4381a797d6a084fa8c9cb80d64 Mon Sep 17 00:00:00 2001 From: Aswin P Kumar Date: Sat, 5 Oct 2024 14:46:01 +0530 Subject: [PATCH] Added a new and innovative Project AES File Encryption Tool --- A/AES-File-Encryption-Tool/README.md | 87 +++++++++++++++++ A/AES-File-Encryption-Tool/aes_tool.py | 128 +++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 A/AES-File-Encryption-Tool/README.md create mode 100644 A/AES-File-Encryption-Tool/aes_tool.py diff --git a/A/AES-File-Encryption-Tool/README.md b/A/AES-File-Encryption-Tool/README.md new file mode 100644 index 00000000..c72b7681 --- /dev/null +++ b/A/AES-File-Encryption-Tool/README.md @@ -0,0 +1,87 @@ +# AES Encryption Tool + +This tool provides a simple interface to encrypt and decrypt files using the AES (Advanced Encryption Standard) encryption algorithm. It uses the AES-CBC mode for encryption, ensuring that your data remains secure and private. A password-based key derivation function (PBKDF2 with HMAC-SHA256) is used to derive the encryption key from the provided password, adding another layer of security. + +## Features + +- **Encrypt Files**: Securely encrypt any file with a password. +- **Decrypt Files**: Decrypt previously encrypted files using the same password. +- **Automatic Padding**: Automatically handles file padding to ensure proper encryption even for files that are not a multiple of the AES block size. +- **Salt and IV Generation**: Generates a random salt and initialization vector (IV) for each encryption to enhance security. + +## Installation + +### Prerequisites: + +1. Python 3.x +2. `cryptography` package + +### To install the required package: + +```bash +pip install cryptography +``` + +## Usage + +### Command-line Arguments + +- `mode`: Choose between `encrypt` or `decrypt` mode. +- `input_file`: The path to the file you want to encrypt or decrypt. +- `output_file` (optional): The desired path for the encrypted or decrypted output file. If not provided, the tool will generate a default name: + - For encryption: `input_file.enc` + - For decryption: If the input file ends with `.enc`, it will remove this extension, otherwise it appends `.dec`. + +### Encrypting a File + +```bash +python aes_tool.py encrypt +``` + +**Example:** + +```bash +python aes_tool.py encrypt example.txt +``` + +This will prompt you for a password and create an encrypted file called `example.txt.enc`. + +### Decrypting a File + +```bash +python aes_tool.py decrypt +``` + +**Example:** + +```bash +python aes_tool.py decrypt example.txt.enc +``` + +This will prompt you for the password and decrypt the file to `example.txt`. + +### Important Notes: + +- You must remember the password used for encryption. The same password is required for decryption. +- If you provide an incorrect password during decryption, the tool will notify you of the failure and delete any incomplete output files to prevent corruption. + +## How It Works + +1. **Encryption:** + + - The tool generates a random 16-byte salt and initialization vector (IV). + - The salt is used with PBKDF2HMAC (HMAC-SHA256) to derive a cryptographic key from the password. + - AES encryption (in CBC mode) is applied to the input file data. + - The encrypted file contains the salt, IV, and the encrypted data. + +2. **Decryption:** + - The tool reads the salt and IV from the encrypted file. + - It derives the cryptographic key using the same password-based key derivation function (PBKDF2HMAC). + - AES decryption is applied, and the original file content is recovered. + +## Author + +- **Name**: Aswin P Kumar +- **GitHub**: [AswinPKumar01](https://github.com/AswinPKumar01) + +--- diff --git a/A/AES-File-Encryption-Tool/aes_tool.py b/A/AES-File-Encryption-Tool/aes_tool.py new file mode 100644 index 00000000..380553c9 --- /dev/null +++ b/A/AES-File-Encryption-Tool/aes_tool.py @@ -0,0 +1,128 @@ +import os +import sys +import argparse +import getpass +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, padding as sym_padding +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC + +def derive_key(password, salt, key_size): + # Derive a cryptographic key from the password + kdf = PBKDF2HMAC( + algorithm=hashes.SHA256(), + length=key_size // 8, + salt=salt, + iterations=100000, + backend=default_backend() + ) + key = kdf.derive(password.encode()) + return key + +def encrypt_file(input_file, output_file, password): + # Generate salt and IV + salt = os.urandom(16) + iv = os.urandom(16) + + # Derive key + key = derive_key(password, salt, 256) + + # Initialize cipher + cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) + encryptor = cipher.encryptor() + + # Read input file and encrypt + with open(input_file, 'rb') as f_in, open(output_file, 'wb') as f_out: + # Write salt and IV to the output file + f_out.write(salt) + f_out.write(iv) + + # Read the file in chunks + while True: + chunk = f_in.read(1024) + if len(chunk) == 0: + break + elif len(chunk) % 16 != 0: + padder = sym_padding.PKCS7(128).padder() + chunk = padder.update(chunk) + padder.finalize() + encrypted_chunk = encryptor.update(chunk) + f_out.write(encrypted_chunk) + # Finalize encryption + f_out.write(encryptor.finalize()) + + print(f"File encrypted successfully: {output_file}") + +def decrypt_file(input_file, output_file, password): + with open(input_file, 'rb') as f_in: + # Read salt and IV from the input file + salt = f_in.read(16) + iv = f_in.read(16) + + # Derive key + key = derive_key(password, salt, 256) + + # Initialize cipher + cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) + decryptor = cipher.decryptor() + + # Prepare to write decrypted data + try: + with open(output_file, 'w+b') as f_out: + # Read the encrypted file in chunks + while True: + chunk = f_in.read(1024) + if len(chunk) == 0: + break + decrypted_chunk = decryptor.update(chunk) + f_out.write(decrypted_chunk) + # Finalize decryption + decrypted_chunk = decryptor.finalize() + f_out.write(decrypted_chunk) + # Remove padding + f_out.seek(0) + data = f_out.read() + unpadder = sym_padding.PKCS7(128).unpadder() + data = unpadder.update(data) + unpadder.finalize() + f_out.seek(0) + f_out.write(data) + f_out.truncate() + print(f"File decrypted successfully: {output_file}") + except Exception as e: + print("Decryption failed. Incorrect password or corrupted file.") + # Ensure the file is closed before deletion + if not f_out.closed: + f_out.close() + if os.path.exists(output_file): + os.remove(output_file) + + +def main(): + parser = argparse.ArgumentParser(description='AES File Encryption Tool') + parser.add_argument('mode', choices=['encrypt', 'decrypt'], help='Mode of operation') + parser.add_argument('input_file', help='Input file path') + parser.add_argument('output_file', nargs='?', help='Output file path') + args = parser.parse_args() + + if not os.path.exists(args.input_file): + print("Input file does not exist.") + sys.exit(1) + + if not args.output_file: + # Generate default output file name + if args.mode == 'encrypt': + args.output_file = args.input_file + '.enc' + else: + if args.input_file.endswith('.enc'): + args.output_file = args.input_file[:-4] + else: + args.output_file = args.input_file + '.dec' + + password = getpass.getpass(prompt='Enter password: ') + + if args.mode == 'encrypt': + encrypt_file(args.input_file, args.output_file, password) + else: + decrypt_file(args.input_file, args.output_file, password) + +if __name__ == '__main__': + main()