Skip to main content

Secure encryption for configuration files using AES-256-GCM + Argon2id

Project description

Shellock ๐Ÿ”

PyPI version Python versions License: MIT Tests codecov

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

  1. The cryptography library is correctly implemented
  2. The operating system's random number generator is secure
  3. The system running Shellock is not compromised
  4. 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

Changelog

See CHANGELOG.md for a list of changes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shellock-0.1.1.tar.gz (43.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shellock-0.1.1-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file shellock-0.1.1.tar.gz.

File metadata

  • Download URL: shellock-0.1.1.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

Hashes for shellock-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e9b12171e84bf683e22a11bc38df61c661606d3312761ae06f8e9777c4a948a3
MD5 344b24c9fb57baf1329b80fc9536681b
BLAKE2b-256 8923e1776bdf5ff9bc4d25a4ec3a19220544149fca781e2d35a57f0a2ea5bf24

See more details on using hashes here.

File details

Details for the file shellock-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: shellock-0.1.1-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

Hashes for shellock-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bd93ed8d4170945c22d9e520d3a2f5d709db0f1254f42cc8f0be357c073a4a5f
MD5 3cb02a14d1b61f674e8e555bce860534
BLAKE2b-256 8084ff16c3569e894b2b5325b213aee0f6da2a3def730dde355f6ca4bb8bcded

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page