Skip to content

Commit a458115

Browse files
committedOct 5, 2024
Added a new and innovative Project AES File Encryption Tool
1 parent 02ab593 commit a458115

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed
 

‎A/AES-File-Encryption-Tool/README.md

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# AES Encryption Tool
2+
3+
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.
4+
5+
## Features
6+
7+
- **Encrypt Files**: Securely encrypt any file with a password.
8+
- **Decrypt Files**: Decrypt previously encrypted files using the same password.
9+
- **Automatic Padding**: Automatically handles file padding to ensure proper encryption even for files that are not a multiple of the AES block size.
10+
- **Salt and IV Generation**: Generates a random salt and initialization vector (IV) for each encryption to enhance security.
11+
12+
## Installation
13+
14+
### Prerequisites:
15+
16+
1. Python 3.x
17+
2. `cryptography` package
18+
19+
### To install the required package:
20+
21+
```bash
22+
pip install cryptography
23+
```
24+
25+
## Usage
26+
27+
### Command-line Arguments
28+
29+
- `mode`: Choose between `encrypt` or `decrypt` mode.
30+
- `input_file`: The path to the file you want to encrypt or decrypt.
31+
- `output_file` (optional): The desired path for the encrypted or decrypted output file. If not provided, the tool will generate a default name:
32+
- For encryption: `input_file.enc`
33+
- For decryption: If the input file ends with `.enc`, it will remove this extension, otherwise it appends `.dec`.
34+
35+
### Encrypting a File
36+
37+
```bash
38+
python aes_tool.py encrypt <input_file> <output_file>
39+
```
40+
41+
**Example:**
42+
43+
```bash
44+
python aes_tool.py encrypt example.txt
45+
```
46+
47+
This will prompt you for a password and create an encrypted file called `example.txt.enc`.
48+
49+
### Decrypting a File
50+
51+
```bash
52+
python aes_tool.py decrypt <input_file> <output_file>
53+
```
54+
55+
**Example:**
56+
57+
```bash
58+
python aes_tool.py decrypt example.txt.enc
59+
```
60+
61+
This will prompt you for the password and decrypt the file to `example.txt`.
62+
63+
### Important Notes:
64+
65+
- You must remember the password used for encryption. The same password is required for decryption.
66+
- 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.
67+
68+
## How It Works
69+
70+
1. **Encryption:**
71+
72+
- The tool generates a random 16-byte salt and initialization vector (IV).
73+
- The salt is used with PBKDF2HMAC (HMAC-SHA256) to derive a cryptographic key from the password.
74+
- AES encryption (in CBC mode) is applied to the input file data.
75+
- The encrypted file contains the salt, IV, and the encrypted data.
76+
77+
2. **Decryption:**
78+
- The tool reads the salt and IV from the encrypted file.
79+
- It derives the cryptographic key using the same password-based key derivation function (PBKDF2HMAC).
80+
- AES decryption is applied, and the original file content is recovered.
81+
82+
## Author
83+
84+
- **Name**: Aswin P Kumar
85+
- **GitHub**: [AswinPKumar01](https://github.com/AswinPKumar01)
86+
87+
---
+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import os
2+
import sys
3+
import argparse
4+
import getpass
5+
from cryptography.hazmat.backends import default_backend
6+
from cryptography.hazmat.primitives import hashes, padding as sym_padding
7+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
8+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
9+
10+
def derive_key(password, salt, key_size):
11+
# Derive a cryptographic key from the password
12+
kdf = PBKDF2HMAC(
13+
algorithm=hashes.SHA256(),
14+
length=key_size // 8,
15+
salt=salt,
16+
iterations=100000,
17+
backend=default_backend()
18+
)
19+
key = kdf.derive(password.encode())
20+
return key
21+
22+
def encrypt_file(input_file, output_file, password):
23+
# Generate salt and IV
24+
salt = os.urandom(16)
25+
iv = os.urandom(16)
26+
27+
# Derive key
28+
key = derive_key(password, salt, 256)
29+
30+
# Initialize cipher
31+
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
32+
encryptor = cipher.encryptor()
33+
34+
# Read input file and encrypt
35+
with open(input_file, 'rb') as f_in, open(output_file, 'wb') as f_out:
36+
# Write salt and IV to the output file
37+
f_out.write(salt)
38+
f_out.write(iv)
39+
40+
# Read the file in chunks
41+
while True:
42+
chunk = f_in.read(1024)
43+
if len(chunk) == 0:
44+
break
45+
elif len(chunk) % 16 != 0:
46+
padder = sym_padding.PKCS7(128).padder()
47+
chunk = padder.update(chunk) + padder.finalize()
48+
encrypted_chunk = encryptor.update(chunk)
49+
f_out.write(encrypted_chunk)
50+
# Finalize encryption
51+
f_out.write(encryptor.finalize())
52+
53+
print(f"File encrypted successfully: {output_file}")
54+
55+
def decrypt_file(input_file, output_file, password):
56+
with open(input_file, 'rb') as f_in:
57+
# Read salt and IV from the input file
58+
salt = f_in.read(16)
59+
iv = f_in.read(16)
60+
61+
# Derive key
62+
key = derive_key(password, salt, 256)
63+
64+
# Initialize cipher
65+
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
66+
decryptor = cipher.decryptor()
67+
68+
# Prepare to write decrypted data
69+
try:
70+
with open(output_file, 'w+b') as f_out:
71+
# Read the encrypted file in chunks
72+
while True:
73+
chunk = f_in.read(1024)
74+
if len(chunk) == 0:
75+
break
76+
decrypted_chunk = decryptor.update(chunk)
77+
f_out.write(decrypted_chunk)
78+
# Finalize decryption
79+
decrypted_chunk = decryptor.finalize()
80+
f_out.write(decrypted_chunk)
81+
# Remove padding
82+
f_out.seek(0)
83+
data = f_out.read()
84+
unpadder = sym_padding.PKCS7(128).unpadder()
85+
data = unpadder.update(data) + unpadder.finalize()
86+
f_out.seek(0)
87+
f_out.write(data)
88+
f_out.truncate()
89+
print(f"File decrypted successfully: {output_file}")
90+
except Exception as e:
91+
print("Decryption failed. Incorrect password or corrupted file.")
92+
# Ensure the file is closed before deletion
93+
if not f_out.closed:
94+
f_out.close()
95+
if os.path.exists(output_file):
96+
os.remove(output_file)
97+
98+
99+
def main():
100+
parser = argparse.ArgumentParser(description='AES File Encryption Tool')
101+
parser.add_argument('mode', choices=['encrypt', 'decrypt'], help='Mode of operation')
102+
parser.add_argument('input_file', help='Input file path')
103+
parser.add_argument('output_file', nargs='?', help='Output file path')
104+
args = parser.parse_args()
105+
106+
if not os.path.exists(args.input_file):
107+
print("Input file does not exist.")
108+
sys.exit(1)
109+
110+
if not args.output_file:
111+
# Generate default output file name
112+
if args.mode == 'encrypt':
113+
args.output_file = args.input_file + '.enc'
114+
else:
115+
if args.input_file.endswith('.enc'):
116+
args.output_file = args.input_file[:-4]
117+
else:
118+
args.output_file = args.input_file + '.dec'
119+
120+
password = getpass.getpass(prompt='Enter password: ')
121+
122+
if args.mode == 'encrypt':
123+
encrypt_file(args.input_file, args.output_file, password)
124+
else:
125+
decrypt_file(args.input_file, args.output_file, password)
126+
127+
if __name__ == '__main__':
128+
main()

0 commit comments

Comments
 (0)
Please sign in to comment.