Skip to content

Commit 524c8fd

Browse files
authored
Merge pull request #41 from haragam22/feature/encryptor-module
Add AES file encryptor/decryptor with password-based key
2 parents 9c62837 + 7f7d7ec commit 524c8fd

File tree

1,137 files changed

+322741
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,137 files changed

+322741
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
2+
# File_Encryption_Decryption
3+
4+
A simple **AES-based file encryption and decryption module** in Python with **password-based key generation**.
5+
Supports encrypting and decrypting any file using a password entered from the command line.
6+
7+
---
8+
9+
## **Features**
10+
11+
* AES encryption (CFB mode)
12+
* Password-based key derivation (PBKDF2HMAC + SHA256)
13+
* Modular code: `utils.py` handles encryption/decryption logic
14+
* CLI-based usage for files
15+
* Supports any file type (images, documents, etc.)
16+
17+
---
18+
19+
## **File Structure**
20+
21+
```
22+
File_Encryption_Decryption/
23+
├── encryptor.py # CLI tool to encrypt files
24+
├── decryptor.py # CLI tool to decrypt files
25+
├── utils.py # Encryption/decryption helper functions
26+
├── requirements.txt # Dependencies
27+
└── sample.jpg # Test file
28+
```
29+
30+
---
31+
32+
## **Installation**
33+
34+
1. Clone the repository:
35+
36+
```bash
37+
git clone https://github.com/haragam22/Code_Script
38+
cd Code_Script/Python/File_Encryption_Decryption
39+
```
40+
41+
2. Create a virtual environment:
42+
43+
```bash
44+
python -m venv venv
45+
```
46+
47+
3. Activate the virtual environment:
48+
49+
```bash
50+
# Windows
51+
venv\Scripts\activate
52+
53+
# macOS/Linux
54+
source venv/bin/activate
55+
```
56+
57+
4. Install dependencies:
58+
59+
```bash
60+
pip install -r requirements.txt
61+
```
62+
63+
---
64+
65+
## **Usage**
66+
67+
### **1. Encrypt a file**
68+
69+
```bash
70+
python encryptor.py <file_path>
71+
```
72+
73+
**Example:**
74+
75+
```bash
76+
python encryptor.py sample.jpg
77+
```
78+
79+
* Enter a password when prompted.
80+
* Creates an encrypted file: `sample.jpg.enc`.
81+
82+
---
83+
84+
### **2. Decrypt a file**
85+
86+
```bash
87+
python decryptor.py <encrypted_file>
88+
```
89+
90+
**Example:**
91+
92+
```bash
93+
python decryptor.py sample.jpg.enc
94+
```
95+
96+
* Enter the **same password** used for encryption.
97+
* Restores the original file: `sample.jpg`.
98+
99+
---
100+
101+
## **Module Functions (utils.py)**
102+
103+
* `generate_key(password: str, salt: bytes = None) -> tuple[bytes, bytes]`
104+
Generates a 256-bit AES key from a password using PBKDF2HMAC. Returns `(key, salt)`.
105+
106+
* `encrypt_data(key: bytes, plaintext: bytes) -> bytes`
107+
Encrypts bytes using AES (CFB mode) and prepends IV.
108+
109+
* `decrypt_data(key: bytes, ciphertext: bytes) -> bytes`
110+
Decrypts bytes using AES (CFB mode). Expects IV prepended.
111+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import sys
2+
from utils import generate_key, decrypt_data
3+
4+
def main():
5+
if len(sys.argv) != 2:
6+
print("Usage: python decryptor.py <encrypted_file>")
7+
sys.exit(1)
8+
9+
file_path = sys.argv[1]
10+
password = input("Enter password: ")
11+
12+
with open(file_path, "rb") as f:
13+
file_data = f.read()
14+
15+
# Extract salt and ciphertext
16+
salt = file_data[:16]
17+
ciphertext = file_data[16:]
18+
19+
# Generate key from password + salt
20+
key, _ = generate_key(password, salt=salt)
21+
22+
try:
23+
plaintext = decrypt_data(key, ciphertext)
24+
except Exception as e:
25+
print("Decryption failed! Wrong password or corrupted file.")
26+
sys.exit(1)
27+
28+
# Save decrypted file
29+
if file_path.endswith(".enc"):
30+
out_file = file_path[:-4]
31+
else:
32+
out_file = file_path + ".dec"
33+
34+
with open(out_file, "wb") as f:
35+
f.write(plaintext)
36+
37+
print(f"File decrypted successfully: {out_file}")
38+
39+
if __name__ == "__main__":
40+
main()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import sys
2+
from utils import generate_key, encrypt_data
3+
import os
4+
5+
def main():
6+
if len(sys.argv) != 2:
7+
print("Usage: python encryptor.py <file_path>")
8+
sys.exit(1)
9+
10+
file_path = sys.argv[1]
11+
password = input("Enter password: ")
12+
13+
# Read file
14+
with open(file_path, "rb") as f:
15+
data = f.read()
16+
17+
# Generate key
18+
key, salt = generate_key(password)
19+
20+
# Encrypt
21+
ciphertext = encrypt_data(key, data)
22+
23+
# Save encrypted file (prepend salt)
24+
out_file = file_path + ".enc"
25+
with open(out_file, "wb") as f:
26+
f.write(salt + ciphertext)
27+
28+
print(f"File encrypted successfully: {out_file}")
29+
30+
if __name__ == "__main__":
31+
main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cryptography==46.0.0
60.8 KB
Loading
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import os
2+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
3+
from cryptography.hazmat.primitives import hashes
4+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
5+
from cryptography.hazmat.backends import default_backend
6+
7+
def generate_key(password: str, salt: bytes = None) -> tuple[bytes, bytes]:
8+
"""
9+
Generate AES key from password using PBKDF2HMAC.
10+
Returns (key, salt)
11+
"""
12+
if salt is None:
13+
salt = os.urandom(16) # Generate random salt
14+
kdf = PBKDF2HMAC(
15+
algorithm=hashes.SHA256(),
16+
length=32, # 256-bit AES key
17+
salt=salt,
18+
iterations=100_000,
19+
backend=default_backend()
20+
)
21+
key = kdf.derive(password.encode())
22+
return key, salt
23+
24+
def encrypt_data(key: bytes, plaintext: bytes) -> bytes:
25+
iv = os.urandom(16) # AES block size
26+
cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend())
27+
encryptor = cipher.encryptor()
28+
ciphertext = encryptor.update(plaintext) + encryptor.finalize()
29+
return iv + ciphertext # prepend IV for decryption
30+
31+
def decrypt_data(key: bytes, ciphertext: bytes) -> bytes:
32+
iv = ciphertext[:16]
33+
actual_ciphertext = ciphertext[16:]
34+
cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend())
35+
decryptor = cipher.decryptor()
36+
plaintext = decryptor.update(actual_ciphertext) + decryptor.finalize()
37+
return plaintext
Binary file not shown.

0 commit comments

Comments
 (0)