Python library for ChaCha20 encryption with PNG-based key storage
Project description
ChaCha Flow - Secure Encryption Library
A comprehensive Python library for symmetric encryption using ChaCha20 with advanced key management and PNG-based secure storage capabilities.
Features
- ChaCha20-Poly1305 AEAD Encryption: Authenticated encryption with associated data
- Secure Key Management: Generate, store, and retrieve cryptographic keys
- PNG-Based Key Storage: Safely embed keys and sensitive data in PNG images using steganography
- Master Key Encryption: Optionally encrypt stored keys with a master key
- Key Rotation: Seamlessly rotate keys with version tracking
- HMAC Verification: Integrity verification of embedded data before deserialization
- Security Logging: Track security events without exposing sensitive data
- File Permission Protection: Automatic secure file permissions (Unix/Windows)
Installation
Prerequisites
- Python 3.8+
- pip
Basic Installation
pip install chacha-flow
Development Installation
pip install -e ".[dev]"
pytest # Run tests
Quick Start
Basic Encryption/Decryption
from chacha_flow import ChaChaCipher
# Generate a key
key = ChaChaCipher.generate_key()
# Create cipher
cipher = ChaChaCipher(key)
# Encrypt
plaintext = b"Secret message"
ciphertext = cipher.encrypt(plaintext)
# Decrypt
decrypted = cipher.decrypt(ciphertext)
assert decrypted == plaintext
Key Management
from chacha_flow import KeyManager
# Create key manager
key_manager = KeyManager()
# Generate and store a key
key = key_manager.generate_key()
key_manager.store_key(key, "my_app_key")
# Load key later
loaded_key = key_manager.load_key("my_app_key")
# Use loaded key
cipher = ChaChaCipher(loaded_key)
ciphertext = cipher.encrypt(b"Hello, World!")
Store Key in PNG Image
from chacha_flow import KeyManager
key_manager = KeyManager()
key = key_manager.generate_key()
# Store key in PNG (creates minimal PNG if no image provided)
key_manager.store_key_in_image(
key,
image_path="original.png",
output_path="secret_key.png"
)
# Load key from PNG
loaded_key = key_manager.load_key_from_image("secret_key.png")
Encrypted Key Storage with Master Key
from chacha_flow import ChaChaCipher, KeyManager
# Generate master key
master_key = ChaChaCipher.generate_key()
# Create manager with encryption
key_manager = KeyManager(master_key=master_key)
# Keys are now stored encrypted
key = key_manager.generate_key()
key_manager.store_key(key, "prod_key") # Encrypted automatically
# Load requires the same master key
loaded_key = key_manager.load_key("prod_key")
Module Overview
ChaChaCipher
ChaCha20-Poly1305 AEAD cipher implementation.
from chacha_flow import ChaChaCipher
# Generate keys and nonces
key = ChaChaCipher.generate_key() # 256-bit key
nonce = ChaChaCipher.generate_nonce() # 96-bit nonce (auto-generated per message)
# Create cipher instance
cipher = ChaChaCipher(key)
# Encrypt
ciphertext = cipher.encrypt(plaintext) # Simple
ciphertext = cipher.encrypt(plaintext, associated_data) # With AAD
# Decrypt
plaintext = cipher.decrypt(ciphertext) # Simple
plaintext = cipher.decrypt(ciphertext, associated_data) # With AAD
# Validate key
is_valid = ChaChaCipher.is_valid_key(key)
Security Properties:
- 256-bit key strength
- 96-bit nonce per message
- Authenticated encryption prevents tampering
- Nonce is automatically included in ciphertext
KeyManager
Centralized key management with multiple storage backends.
from chacha_flow import KeyManager
# Initialize
km = KeyManager() # Default location
km = KeyManager(key_dir="/secure/keys") # Custom location
km = KeyManager(master_key=master_key) # With encryption
# Generate
key = km.generate_key()
# Store
km.store_key(key, "key_name", metadata={...})
# Load
key = km.load_key("key_name")
# List
keys = km.list_keys()
# Rotate
new_key = km.rotate_key("old_name", "new_name")
# Delete
km.delete_key("key_name")
km.delete_all_keys() # WARNING: Irreversible
# Image storage
km.store_key_in_image(key, "original.png", "output.png")
key = km.load_key_from_image("output.png")
ImageKeyStorage
Store serialized objects in PNG images with integrity verification.
from chacha_flow import ImageKeyStorage
# Store object in image
ImageKeyStorage.store_key_in_image(
{"key": b"...", "metadata": {...}},
image_path="source.png", # Optional, creates minimal PNG if omitted
output_path="secret.png",
hmac_key=master_key # Optional, enables integrity verification
)
# Load object from image
obj = ImageKeyStorage.load_key_from_image(
"secret.png",
hmac_key=master_key # Required if HMAC was used during storage
)
Security Considerations
Critical Security Warnings
⚠️ Pickle Deserialization Risk: pickle can execute arbitrary code during deserialization. ONLY load keys from TRUSTED image sources.
⚠️ HMAC Verification: When loading keys from images, always verify HMAC signature if available:
# Good: Verify signature
key = ImageKeyStorage.load_key_from_image(
"image.png",
hmac_key=trusted_master_key # Verification required
)
# Bad: No verification
key = ImageKeyStorage.load_key_from_image("untrusted_image.png")
⚠️ Master Key Protection: Protect master keys like passwords - if compromised, all encrypted keys are exposed.
Best Practices
- Always verify image sources: Only load from trusted origins
- Use HMAC when possible: Enable signature verification
- Store securely: Use restricted file permissions (automatic)
- Rotate regularly: Change keys periodically
- Monitor logs: Check for security events without exposing keys
- Backup keys: Keep encrypted backups of critical keys
- Different keys per environment: Use separate keys for dev/staging/production
File Permissions
- Unix/Linux: Files automatically saved with
0o600permissions (owner read/write only) - Windows: Files saved with restricted access for the current user
- Verification: Permissions are checked before loading sensitive files
Master Key Recommendations
# Generate strong master key
master_key = ChaChaCipher.generate_key()
# Store it VERY securely:
# - Never hardcode in source
# - Use environment variables or secure vaults
# - Consider hardware security modules (HSM)
master_key = os.environ.get("CHACHA_MASTER_KEY")
if not master_key:
raise ValueError("Master key not configured")
km = KeyManager(master_key=master_key)
Configuration
Edit chacha_flow/config.py to customize:
# Cryptographic parameters
CHACHA20_KEY_SIZE = 32 # 256-bit keys
CHACHA20_NONCE_SIZE = 12 # 96-bit nonces
# Image storage
MAX_IMAGE_SIZE_MB = 50 # Maximum image size
STORAGE_METHOD = "eof" # "eof" (default) or "lsb"
# Key storage
DEFAULT_KEY_DIR = "~/.chacha_flow/keys"
KEY_PERMISSIONS = 0o600 # Unix file permissions
# Security
ENABLE_HMAC_VERIFICATION = True
HMAC_ALGORITHM = "sha256"
# Logging
LOG_LEVEL = "INFO"
Examples
Example 1: Secure Configuration Storage
from chacha_flow import KeyManager, ChaChaCipher
# Generate and store configuration key
km = KeyManager()
config_key = km.generate_key()
km.store_key(config_key, "config_encryption_key")
# Encrypt configuration
config = {"database": "postgresql://...", "api_token": "secret"}
cipher = ChaChaCipher(config_key)
encrypted_config = cipher.encrypt(json.dumps(config).encode())
# Save encrypted config to file
with open("config.encrypted", "wb") as f:
f.write(encrypted_config)
# Load and decrypt later
with open("config.encrypted", "rb") as f:
encrypted_config = f.read()
cipher = ChaChaCipher(km.load_key("config_encryption_key"))
config = json.loads(cipher.decrypt(encrypted_config).decode())
Example 2: Multi-Environment Key Management
from chacha_flow import KeyManager
km = KeyManager()
# Generate environment-specific keys
for env in ["dev", "staging", "production"]:
key = km.generate_key()
km.store_key(key, f"app_key_{env}")
# Load based on environment
import os
env = os.environ["APP_ENV"]
key = km.load_key(f"app_key_{env}")
Example 3: Backup Keys in Images
from chacha_flow import KeyManager
km = KeyManager()
# Create backup of production key in image
prod_key = km.load_key("production")
km.store_key_in_image(
prod_key,
image_path="backup_template.png",
output_path="/secure/backup/prod_key_backup.png"
)
# Restore from backup if needed
restored_key = km.load_key_from_image("/secure/backup/prod_key_backup.png")
km.store_key(restored_key, "production")
Testing
Run the comprehensive test suite:
# Install test dependencies
pip install -e ".[dev]"
# Run all tests
pytest test_chacha_flow.py -v
# Run specific test class
pytest test_chacha_flow.py::TestChaChaCipher -v
# Run with coverage
pytest test_chacha_flow.py --cov=chacha_flow
Running Examples
python examples.py
Output shows:
- Basic encryption/decryption
- Local key storage and retrieval
- Image-based key storage
- Encrypted key storage with master key
- Complete workflows
- Key rotation
Architecture
chacha_flow/
├── __init__.py # Package exports
├── chacha_cipher.py # ChaCha20-Poly1305 encryption
├── key_manager.py # Key generation and management
├── image_storage.py # PNG steganography
├── config.py # Configuration
└── utils.py # Utilities (logging, security, HMAC)
Logging
Security events are logged without exposing sensitive data:
import logging
logging.basicConfig(level=logging.INFO)
# Logs include:
# - Key generation/rotation/deletion
# - Load/store operations
# - HMAC verification status
# - Invalid image/data detection
# - NO actual keys or plaintext
Dependencies
- cryptography >= 41.0.0 - Cryptographic primitives
- pillow >= 10.0.0 - Image processing
FAQ
Q: Can I store other data besides keys? A: Yes! ImageKeyStorage can store any Python object via pickle.
ImageKeyStorage.store_key_in_image(
{"config": {...}, "settings": {...}},
output_path="backup.png"
)
Q: What if I lose my master key? A: All encrypted keys become unrecoverable. Always keep secure backups and use key rotation.
Q: Is this suitable for production? A: Yes, but ensure proper key management procedures:
- Store master keys securely (vaults, HSM, etc.)
- Regularly rotate keys
- Monitor security logs
- Audit access patterns
- Use in combination with at-rest encryption
Q: Can I use custom image processing?
A: Yes, modify image_storage.py for custom steganography methods.
Performance
- Key generation: ~1ms
- Encryption (1KB): ~2ms
- Decryption (1KB): ~2ms
- Image embedding: ~100ms (depends on image size)
License
MIT License - See LICENSE file
Contributing
Contributions welcome! Please:
- Add tests for new features
- Follow existing code style
- Update documentation
- Test on Python 3.8+
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 chacha_flow-1.0.0.tar.gz.
File metadata
- Download URL: chacha_flow-1.0.0.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
951f8311f8c1eb4d6b44c3c36419a55e65791d0ba0c564443da60ad740a8fcaf
|
|
| MD5 |
3949b0b50942948cd70ea4c31a2def28
|
|
| BLAKE2b-256 |
3f21f49242cef695a05cdae98862e255ae326e7c7c4d792a57a64c35f154e110
|
File details
Details for the file chacha_flow-1.0.0-py3-none-any.whl.
File metadata
- Download URL: chacha_flow-1.0.0-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
910ccda886dc7b4d342f0e226e899001747f42c42db683899f6ae1478c224b52
|
|
| MD5 |
2220c9c757f02441700645eeb9698280
|
|
| BLAKE2b-256 |
493893de103faeeda43783f760a098c7d2913cd5daaf5b2cd09db81b39891299
|