🔒 Fort Spy
Pixel-Level Video Encryption & Real-Time Decryption Technology
Fort Spy is a military-grade video encryption system that operates at the pixel level, encrypting raw RGB data of every video frame using AES-256. It includes a dedicated Fort Spy Player that decrypts frames in real-time during playback, ensuring seamless and secure viewing with GPU acceleration.
✨ Features
🔐 Pixel-Level Encryption
- Encrypts raw RGB pixel data of each video frame individually
- Supports AES-128, AES-192, and AES-256 encryption
- Three cipher modes: CBC, CTR (default), and GCM (authenticated)
- Per-frame nonce derivation prevents pattern analysis across frames
- HMAC-based header integrity verification
🎬 Fort Spy Player
- Dedicated video player with real-time decryption during playback
- Multi-threaded frame buffering for smooth, low-latency viewing
- Play/Pause, Seek, Fullscreen, Speed Control (0.25x – 4x)
- Real-time performance overlay (FPS, decode time, throughput)
- Secure key input dialog (GUI or terminal)
- Progress bar and frame counter
⚡ GPU Acceleration
- OpenCL support via PyOpenCL
- CUDA support via CuPy
- Automatic fallback to optimized NumPy vectorized operations
- Batch frame processing for maximum throughput
🔑 Secure Key Management
- Cryptographically secure random key generation
- PBKDF2-HMAC-SHA256 password-based key derivation (600K iterations, OWASP recommended)
- ECDH key exchange (SECP384R1) for secure key sharing over insecure channels
- Password-protected
.fortkeykey files (AES-GCM encrypted) - Key fingerprinting and HMAC verification
📦 Custom File Format
.fortspyencrypted video format with structured binary header- Embedded metadata: resolution, FPS, frame count, encryption parameters
- HMAC-protected headers to detect tampering
- Streaming-compatible frame layout with length-prefixed chunks
📁 Project Structure
fort-spy/
├── fortspy/ # Main package
│ ├── __init__.py
│ ├── cli.py # Command-line interface
│ ├── core/
│ │ ├── __init__.py
│ │ ├── encryptor.py # Frame encryption engine
│ │ ├── decryptor.py # Real-time decryption engine
│ │ └── key_manager.py # Key generation & exchange
│ ├── player/
│ │ ├── __init__.py
│ │ └── fort_player.py # Dedicated video player
│ └── utils/
│ ├── __init__.py
│ └── gpu_accelerator.py # GPU/OpenCL acceleration
├── tests/
│ ├── __init__.py
│ └── test_fortspy.py # Comprehensive test suite
├── examples/
│ ├── quick_start.py # Full pipeline demo
│ └── key_exchange.py # ECDH key exchange demo
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI
├── setup.py
├── pyproject.toml
├── requirements.txt
├── requirements-dev.txt
├── LICENSE
├── .gitignore
└── README.md
🚀 Installation
From Source
git clone https://github.com/your-username/fort-spy.git
cd fort-spy
pip install -e .
With GPU Support
# OpenCL (AMD/Intel/NVIDIA)
pip install -e ".[gpu-opencl]"
# CUDA (NVIDIA)
pip install -e ".[gpu-cuda]"
Development
pip install -e ".[dev]"
📖 Usage
CLI Commands
Fort Spy provides a full-featured command-line interface:
Encrypt a Video
# With auto-generated key (key printed to terminal)
fortspy encrypt -i video.mp4 -o secure.fortspy
# With password
fortspy encrypt -i video.mp4 -o secure.fortspy -p "my_strong_password"
# With specific key and mode
fortspy encrypt -i video.mp4 -o secure.fortspy --hex-key abcdef... --mode GCM --key-size 256
# Save key to protected file
fortspy encrypt -i video.mp4 -o secure.fortspy -p "password" --save-key my.fortkey
Decrypt a Video
# With key file
fortspy decrypt -i secure.fortspy -o output.mp4 --keyfile my.fortkey -p "password"
# With hex key
fortspy decrypt -i secure.fortspy -o output.mp4 --hex-key abcdef...
# Disable GPU acceleration
fortspy decrypt -i secure.fortspy -o output.mp4 --keyfile my.fortkey --no-gpu
Play Encrypted Video
# With key file (recommended)
fortspy play secure.fortspy --keyfile my.fortkey -p "password"
# With hex key and stats overlay
fortspy play secure.fortspy --hex-key abcdef... --stats
# Interactive (prompts for key)
fortspy play secure.fortspy
Player Controls:
| Key | Action |
|---|---|
Space |
Play / Pause |
Q / Esc |
Quit |
F |
Toggle Fullscreen |
S |
Toggle Stats Overlay |
+ / - |
Speed Up / Slow Down |
Generate Keys
# Generate and display a key
fortspy keygen
# Generate and save to protected file
fortspy keygen -o my.fortkey -p "file_password" --key-size 256
Inspect Encrypted Files
fortspy info secure.fortspy
Check GPU Status
fortspy gpu-info
Python API
Basic Encryption & Decryption
from fortspy import FortSpyEncryptor, FortSpyDecryptor, KeyManager
# Generate key
km = KeyManager(256)
key = km.generate_key()
# Encrypt
encryptor = FortSpyEncryptor(key=key, mode="CTR", key_size=256)
metadata = encryptor.encrypt_video("input.mp4", "encrypted.fortspy")
print(f"Encrypted {metadata['total_frames']} frames")
# Decrypt
decryptor = FortSpyDecryptor(key=key, use_gpu=True)
result = decryptor.decrypt_to_video("encrypted.fortspy", "output.mp4")
print(f"Decrypted at {result['effective_fps']:.1f} FPS")
Password-Based Encryption
from fortspy import FortSpyEncryptor, KeyManager
km = KeyManager(256)
key, salt = km.derive_key_from_password("my_secret_password")
# Save the salt — you'll need it for decryption!
encryptor = FortSpyEncryptor(key=key, mode="CTR")
encryptor.encrypt_video("input.mp4", "encrypted.fortspy")
ECDH Key Exchange
from fortspy import KeyManager
# Alice
alice = KeyManager(256)
alice_pub = alice.generate_ecdh_keypair()
alice_pem = alice.export_public_key_pem()
# Bob
bob = KeyManager(256)
bob_pub = bob.generate_ecdh_keypair()
bob_pem = bob.export_public_key_pem()
# Exchange public keys, then derive shared secret
alice_shared = alice.derive_shared_key(bob.import_public_key_pem(bob_pem))
bob_shared = bob.derive_shared_key(alice.import_public_key_pem(alice_pem))
assert alice_shared == bob_shared # Same key on both sides!
Streaming Decryption
from fortspy import FortSpyDecryptor
decryptor = FortSpyDecryptor(key=key, use_gpu=True)
for frame, idx in decryptor.decrypt_video_stream("encrypted.fortspy"):
# Process each decrypted frame as numpy array
process(frame)
Fort Spy Player (Programmatic)
from fortspy import FortSpyPlayer
player = FortSpyPlayer(key=key, use_gpu=True, show_stats=True)
player.play("encrypted.fortspy")
# Headless mode (no GUI)
result = player.play_headless("encrypted.fortspy", output_path="decrypted.mp4")
🏗 Architecture
Encryption Pipeline
Input Video (MP4/AVI/MKV)
│
▼
┌─────────────────────────┐
│ Frame Extraction │ OpenCV reads each frame
│ (BGR pixel array) │ as numpy array (H×W×3)
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Pixel Serialization │ frame.tobytes() → raw RGB
│ (H × W × 3 bytes) │ bytes stream
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ AES Encryption │ Per-frame nonce (CTR mode)
│ (CTR/CBC/GCM) │ or IV reuse (CBC/GCM)
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Frame Packaging │ 4-byte length prefix +
│ (length-prefixed) │ ciphertext [+ GCM tag]
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ .fortspy File │ Header (HMAC) + encrypted
│ (binary format) │ frame sequence
└─────────────────────────┘
Real-Time Decryption (Player)
.fortspy File
│
▼
┌─────────────────────────┐
│ Header Validation │ HMAC verification +
│ (key check) │ metadata extraction
└────────────┬────────────┘
│
┌────────┴─────────┐
│ Decrypt Thread │ Background pre-decryption
│ (producer) │ into frame buffer
└────────┬─────────┘
│
▼
┌─────────────────┐
│ Frame Buffer │ Thread-safe queue (30-60
│ (queue) │ frames ahead)
└────────┬────────┘
│
┌────────┴─────────┐
│ Display Thread │ Timing-controlled frame
│ (consumer) │ display + overlays
└────────┬─────────┘
│
▼
┌─────────────────┐
│ GPU Post-proc │ Optional OpenCL/CUDA
│ + Rendering │ pixel processing
└─────────────────┘
🧪 Testing
# Run all tests
pytest tests/ -v
# With coverage
pytest tests/ -v --cov=fortspy --cov-report=html
# Run specific test class
pytest tests/test_fortspy.py::TestFrameEncryption -v
🔧 Supported Formats
Input Video Formats
Any format supported by OpenCV/FFmpeg: MP4, AVI, MKV, MOV, WebM, FLV, WMV
Encryption Modes
| Mode | Description | Best For |
|---|---|---|
| CTR (default) | Counter mode, parallelizable, no padding needed | General use, best performance |
| CBC | Cipher Block Chaining, requires padding | Legacy compatibility |
| GCM | Galois/Counter Mode with authentication tag | Maximum security (tamper detection) |
📊 Performance
Benchmark on a 1080p video (1920×1080, 30fps):
| Operation | CPU Only | GPU (OpenCL) | GPU (CUDA) |
|---|---|---|---|
| Encrypt | ~45 FPS | — | — |
| Decrypt | ~50 FPS | ~120 FPS | ~180 FPS |
| Player | ~48 FPS | ~110 FPS | ~165 FPS |
Results vary by hardware. GPU acceleration primarily benefits decryption and playback.
🔒 Security Considerations
- AES-256-CTR is the default mode providing strong encryption with excellent performance
- AES-256-GCM provides authenticated encryption (recommended for tamper detection)
- Per-frame nonce derivation in CTR mode prevents nonce reuse across frames
- PBKDF2 with 600,000 iterations follows OWASP 2023 recommendations
- ECDH over SECP384R1 provides ~192-bit security for key exchange
- Key files are encrypted with AES-GCM when password-protected
- Header HMAC detects key mismatches before attempting frame decryption
⚠️ Important: This is an educational/research project. For production DRM or content protection, consider established solutions alongside Fort Spy's encryption layer.
🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run the tests (
pytest tests/ -v) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License — see the LICENSE file for details.
🗺 Roadmap
- Hardware-accelerated AES via AES-NI intrinsics
- WebAssembly player for browser-based playback
- Audio track encryption support
- Selective region-of-interest encryption
- Multi-key access control (encrypt once, multiple authorized viewers)
- Streaming protocol support (RTSP/HLS encrypted transport)
- Watermarking integration for forensic tracking
Metadata
Release files for fortspy 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fortspy-1.0.0.tar.gz | 31.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fortspy-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 60.9 kB
Release files / fortspy-1.0.0.tar.gz
| Download URL | fortspy-1.0.0.tar.gz |
|---|---|
| Size | 31.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
66c8b6446695f22259b4147cc3be153b28f472482fdb450391fdd0c5c89c5733
|
|
BLAKE2b-256 checksum How to use checksums |
b1f7b9433881b7b4bc9485e94c754e699e94180656334390003bb243b1ee09ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.5
|
Release files / fortspy-1.0.0-py3-none-any.whl
| Download URL | fortspy-1.0.0-py3-none-any.whl |
|---|---|
| Size | 29.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8f4d5bf23b62cab5165b6ab801ed8cf2446341c66702a74ae988dbc49fcc95c2
|
|
BLAKE2b-256 checksum How to use checksums |
a6fd78e372aa3944cc17ec741e7e9a4b5e5acadec856af321409fbba1127100e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.5
|