-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a new and innovative Project AES File Encryption Tool
- Loading branch information
1 parent
02ab593
commit a458115
Showing
2 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <input_file> <output_file> | ||
``` | ||
|
||
**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 <input_file> <output_file> | ||
``` | ||
|
||
**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) | ||
|
||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |