Skip to main content

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

  1. Always verify image sources: Only load from trusted origins
  2. Use HMAC when possible: Enable signature verification
  3. Store securely: Use restricted file permissions (automatic)
  4. Rotate regularly: Change keys periodically
  5. Monitor logs: Check for security events without exposing keys
  6. Backup keys: Keep encrypted backups of critical keys
  7. Different keys per environment: Use separate keys for dev/staging/production

File Permissions

  • Unix/Linux: Files automatically saved with 0o600 permissions (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:

  1. Add tests for new features
  2. Follow existing code style
  3. Update documentation
  4. Test on Python 3.8+

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

chacha_flow-1.0.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

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

chacha_flow-1.0.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

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

Hashes for chacha_flow-1.0.0.tar.gz
Algorithm Hash digest
SHA256 951f8311f8c1eb4d6b44c3c36419a55e65791d0ba0c564443da60ad740a8fcaf
MD5 3949b0b50942948cd70ea4c31a2def28
BLAKE2b-256 3f21f49242cef695a05cdae98862e255ae326e7c7c4d792a57a64c35f154e110

See more details on using hashes here.

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

Hashes for chacha_flow-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 910ccda886dc7b4d342f0e226e899001747f42c42db683899f6ae1478c224b52
MD5 2220c9c757f02441700645eeb9698280
BLAKE2b-256 493893de103faeeda43783f760a098c7d2913cd5daaf5b2cd09db81b39891299

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