Secure encryption for configuration files using AES-256-GCM + Argon2id
Project description
Shellock ๐
Secure encryption for configuration files using AES-256-GCM + Argon2id.
Overview
Shellock is a Python tool for encrypting and decrypting configuration files (like .env files) using modern cryptographic primitives. It provides both a command-line interface and a Python API with security-first design principles.
Security Guarantees
Shellock is designed with security as the primary concern:
- Strong Encryption: AES-256-GCM provides authenticated encryption with 256-bit security
- Memory-Hard Key Derivation: Argon2id (OWASP recommended parameters) protects against brute-force attacks
- Authenticated Encryption: GCM mode ensures both confidentiality and integrity
- Random Salt & Nonce: Each encryption uses cryptographically secure random values
- Constant-Time Operations: Prevents timing side-channel attacks
- Secure Memory Handling: Sensitive data is cleared from memory after use
- No Information Leakage: Generic error messages prevent oracle attacks
Cryptographic Parameters
| Parameter | Value | Standard |
|---|---|---|
| Encryption | AES-256-GCM | NIST SP 800-38D |
| Key Derivation | Argon2id | RFC 9106 |
| Memory Cost | 64 MB | OWASP recommendation |
| Time Cost | 2 iterations | OWASP recommendation |
| Parallelism | 4 threads | OWASP recommendation |
| Salt Size | 16 bytes | Best practice |
| Nonce Size | 12 bytes | GCM standard |
| Key Size | 32 bytes | AES-256 |
Features
- Multiple Encryption Modes:
- Passphrase-based encryption (Argon2id + AES-256-GCM)
- Symmetric key-based encryption (direct AES-256-GCM)
- Asymmetric encryption (X25519 + AES-256-GCM hybrid)
- Rich CLI: Beautiful command-line interface with progress indicators
- Python API: Clean, type-annotated API for programmatic access
- Cross-Platform: Works on Linux, macOS, and Windows
- Modern Python: Supports Python 3.8+
Installation
From PyPI (Recommended)
pip install shellock
From Source
git clone https://github.com/Madan2248c/shellock.git
cd shellock
pip install -e .
With Development Dependencies
pip install -e ".[dev]"
Quick Start
CLI Usage
Passphrase-Based Encryption
# Encrypt a file (will prompt for passphrase)
shellock encrypt config.env --out config.env.enc
# Encrypt with passphrase on command line (less secure)
shellock encrypt config.env --out config.env.enc --passphrase "my-secret"
# Decrypt a file
shellock decrypt config.env.enc --out config.env
Symmetric Key Encryption
# Generate a symmetric key
shellock generate-key --type symmetric --out secret.key
# Encrypt with the key file
shellock encrypt-key config.env --key secret.key --out config.env.enc
# Decrypt with the key file
shellock decrypt-key config.env.enc --key secret.key --out config.env
Asymmetric (Public Key) Encryption
# Generate a keypair
shellock generate-key --type asymmetric --out private.pem
# (Public key is displayed - save it to a file)
# Encrypt with public key (anyone can encrypt)
shellock encrypt-public config.env --key public.pem --out config.env.enc
# Decrypt with private key (only key holder can decrypt)
shellock decrypt-private config.env.enc --key private.pem --out config.env
CLI Help
# General help
shellock --help
# Command-specific help
shellock encrypt --help
shellock decrypt --help
shellock generate-key --help
Python API
Basic Encryption/Decryption
from shellock import encrypt_file, decrypt_file
# Encrypt a file with a passphrase
encrypt_file("config.env", "config.env.enc", "my-secure-passphrase")
# Decrypt a file
decrypt_file("config.env.enc", "config.env", "my-secure-passphrase")
Byte-Level Operations
from shellock import encrypt_bytes, decrypt_bytes
# Encrypt bytes
plaintext = b"SECRET_KEY=abc123\nDB_PASSWORD=hunter2"
encrypted = encrypt_bytes(plaintext, "my-passphrase")
# Decrypt bytes
decrypted = decrypt_bytes(encrypted, "my-passphrase")
assert decrypted == plaintext
Symmetric Key Operations
import secrets
import base64
from shellock import encrypt_bytes_key, decrypt_bytes_key, KEY_SIZE
# Generate a random key
key = secrets.token_bytes(KEY_SIZE) # 32 bytes
# Encrypt with the key
plaintext = b"sensitive data"
encrypted = encrypt_bytes_key(plaintext, key)
# Decrypt with the key
decrypted = decrypt_bytes_key(encrypted, key)
assert decrypted == plaintext
# Save key to file (base64 encoded)
with open("secret.key", "w") as f:
f.write(base64.b64encode(key).decode())
Asymmetric Encryption
from shellock import (
generate_keypair,
encrypt_bytes_public,
decrypt_bytes_private,
)
# Generate a keypair
private_key_pem, public_key_pem = generate_keypair()
# Save keys
with open("private.pem", "wb") as f:
f.write(private_key_pem)
with open("public.pem", "wb") as f:
f.write(public_key_pem)
# Encrypt with public key
plaintext = b"secret message"
encrypted = encrypt_bytes_public(plaintext, public_key_pem)
# Decrypt with private key
decrypted = decrypt_bytes_private(encrypted, private_key_pem)
assert decrypted == plaintext
Error Handling
from shellock import (
encrypt_file,
decrypt_file,
InvalidFileFormatError,
AuthenticationError,
)
try:
decrypt_file("encrypted.env", "decrypted.env", "wrong-passphrase")
except InvalidFileFormatError:
print("The file is not a valid Shellock encrypted file")
except AuthenticationError:
print("Wrong passphrase or file has been tampered with")
except FileNotFoundError as e:
print(f"File not found: {e}")
Security Best Practices
Passphrase Guidelines
- Use a strong, unique passphrase (16+ characters recommended)
- Consider using a passphrase manager
- Never commit passphrases to version control
- Use environment variables or secure vaults in production
Key Management
# DO: Generate keys with secure random
import secrets
key = secrets.token_bytes(32)
# DON'T: Use predictable values
key = b"my-weak-key-1234567890123456" # BAD!
File Permissions
Shellock automatically sets secure permissions (600) on output files. For key files:
# Ensure key files are protected
chmod 600 private.pem secret.key
Environment Variables
For CI/CD and production environments:
# Store passphrase in environment variable
export SHELLOCK_PASSPHRASE="your-secure-passphrase"
# Use in scripts
shellock decrypt config.env.enc --out config.env --passphrase "$SHELLOCK_PASSPHRASE"
Threat Model & Limitations
What Shellock Protects Against
- โ Unauthorized access to encrypted files at rest
- โ Brute-force attacks on passphrases (via Argon2id)
- โ Tampering detection (via GCM authentication)
- โ Rainbow table attacks (via random salts)
- โ Replay attacks (via random nonces)
What Shellock Does NOT Protect Against
- โ Compromised systems where attacker has memory access
- โ Keyloggers capturing passphrases
- โ Weak passphrases (use strong passphrases!)
- โ Side-channel attacks on the underlying hardware
- โ Quantum computing attacks (future consideration)
Security Assumptions
- The
cryptographylibrary is correctly implemented - The operating system's random number generator is secure
- The system running Shellock is not compromised
- Passphrases are kept secret and are sufficiently strong
Development
Setup
# Clone the repository
git clone https://github.com/Madan2248c/shellock.git
cd shellock
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=shellock --cov-report=html
# Run property-based tests with more examples
pytest -m property --hypothesis-profile=ci
# Run security-focused tests
pytest -m security
Code Quality
# Format code
ruff format .
# Lint code
ruff check .
# Type check
mypy shellock/
# Run all checks (via pre-commit)
pre-commit run --all-files
Project Structure
shellock/
โโโ shellock/
โ โโโ __init__.py # Package exports
โ โโโ api.py # File-based API
โ โโโ cli.py # Click CLI
โ โโโ crypto.py # Core cryptographic operations
โ โโโ exceptions.py # Custom exceptions
โโโ tests/
โ โโโ test_api.py # API tests
โ โโโ test_cli.py # CLI tests
โ โโโ test_crypto.py # Crypto tests (unit + property)
โโโ docs/
โ โโโ README.md # Additional documentation
โโโ pyproject.toml # Project configuration
โโโ README.md # This file
โโโ LICENSE # MIT License
โโโ SECURITY.md # Security policy
โโโ CHANGELOG.md # Version history
Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Reporting Security Issues
Please do not report security vulnerabilities through public GitHub issues.
Instead, please report them via our Security Policy. See the security policy for details on our responsible disclosure process.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- cryptography - The excellent Python cryptographic library
- Click - CLI framework
- Rich - Beautiful terminal formatting
- Hypothesis - Property-based testing
Changelog
See CHANGELOG.md for a list of changes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shellock-0.1.2.tar.gz.
File metadata
- Download URL: shellock-0.1.2.tar.gz
- Upload date:
- Size: 43.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c5ba9a0aef411607c3e2bf46115f6484564b1c83f91d97cb7866208b03b5c36
|
|
| MD5 |
fac0e85e13a044e05da4de6ed5f13e51
|
|
| BLAKE2b-256 |
a475e754852098b909f49de6bf496f9341d8c4e3090cd9d740c59a9224b271e6
|
File details
Details for the file shellock-0.1.2-py3-none-any.whl.
File metadata
- Download URL: shellock-0.1.2-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5be77c1bf732af616bec55787869cb3a3a695e9fb019407e56daf8b7cdbe01b1
|
|
| MD5 |
e0d2b8b3991935082a0b10a3be7e5826
|
|
| BLAKE2b-256 |
fc78a8d8b373fa4d0d48bf46d7f49ec69071536d6c2c821bbc4fa75512aa0997
|