# File Encryption Tool

This utility encrypts and decrypts files using symmetric encryption provided by the `cryptography` library. It uses the Fernet implementation, which guarantees that a message encrypted using it cannot be manipulated or read without the key.

**Modules Used:**
*   `cryptography`: For generating keys and performing encryption/decryption.
*   [[programming/python/modules/argparse-module|argparse]]: To handle command-line arguments.
*   `os`: To check for file existence.

## Installation

You need to install the `cryptography` library:

```bash
pip install cryptography
```

## The Code

Save this as `encryptor.py`.

```python
from cryptography.fernet import Fernet
import argparse
import os

def generate_key(key_file="secret.key"):
    """Generates a key and saves it into a file."""
    key = Fernet.generate_key()
    with open(key_file, "wb") as kf:
        kf.write(key)
    print(f"Key generated and saved to {key_file}")

def load_key(key_file="secret.key"):
    """Loads the key from the current directory."""
    return open(key_file, "rb").read()

def process_file(filename, key, mode):
    """Encrypts or Decrypts a file."""
    f = Fernet(key)
    
    with open(filename, "rb") as file:
        file_data = file.read()
    
    try:
        if mode == 'encrypt':
            processed_data = f.encrypt(file_data)
            print(f"File '{filename}' encrypted.")
        else:
            processed_data = f.decrypt(file_data)
            print(f"File '{filename}' decrypted.")
            
        with open(filename, "wb") as file:
            file.write(processed_data)
            
    except Exception as e:
        print(f"Error processing file (Invalid Key?): {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="File Encryptor/Decryptor")
    parser.add_argument("action", choices=['generate', 'encrypt', 'decrypt'], help="Action to perform")
    parser.add_argument("filename", nargs="?", help="File to encrypt/decrypt")
    parser.add_argument("--key", default="secret.key", help="Key file path (default: secret.key)")

    args = parser.parse_args()

    if args.action == "generate":
        generate_key(args.key)
    elif args.action in ["encrypt", "decrypt"]:
        if not args.filename:
            print("Error: Filename required for encryption/decryption.")
        elif not os.path.exists(args.filename):
            print(f"Error: File '{args.filename}' not found.")
        elif not os.path.exists(args.key):
             print(f"Error: Key file '{args.key}' not found. Generate one first.")
        else:
            key = load_key(args.key)
            process_file(args.filename, key, args.action)
```

## Usage

```bash
# 1. Generate a key (do this once)
python encryptor.py generate

# 2. Encrypt a file
python encryptor.py encrypt confidential.txt

# 3. Decrypt a file
python encryptor.py decrypt confidential.txt
```

**Warning:** If you lose `secret.key`, you will not be able to decrypt your files.

[[programming/python/python]]