Hide encrypted PDFs ( let me correct that; every file type ) inside MP4 video files using a custom matrix-based stream cipher. A Go CLI tool for steganography that embeds password-protected documents into video containers without altering playback.
- Overview
- Features
- How It Works
- Installation
- Usage
- Architecture
- Technical Details
- Examples
- Contributing
- License
ShadowBox is a steganography tool that enables you to conceal encrypted PDF documents within MP4 video files. The project uses a custom matrix-based stream cipher for encryption combined with MP4 container manipulation to seamlessly embed data without affecting video playback.
Perfect for:
- Confidential document distribution via video files
- Secure data hiding in plain sight
- Privacy-focused file sharing
- Proof-of-concept steganography research
✨ Custom Matrix Cipher
- Proprietary 4×4 matrix-based stream cipher
- Diffusion through matrix multiplication (mod 256)
- Efficient XOR-based encryption/decryption
🎬 MP4 Native
- Embeds data directly in MP4
mdatbox (media data) - Preserves video playback functionality
- Transparent to media players
🔐 Password Protected
- PBKDF2 key derivation from passwords
- SHA-256 hashing
- 4096 iterations for enhanced security
🚀 Command-Line Interface
- Simple two-mode operation:
embedandextract - Robust error handling
- File-based I/O
- Load Files: Read the carrier MP4 and secret PDF
- Derive Key: Generate encryption key from password using PBKDF2
- Encrypt PDF: Use matrix cipher to encrypt PDF data
- Locate mdat Box: Find the media data box in MP4 structure
- Append Data: Insert encrypted PDF with metadata marker into mdat payload
- Write Output: Save modified MP4 with embedded data
- Load MP4: Read the embedded MP4 file
- Find Marker: Locate the magic marker ("MPDP") in mdat box
- Extract Metadata: Read original payload size and PDF size
- Recover Encrypted Data: Extract encrypted PDF from mdat
- Derive Key: Regenerate encryption key from password
- Decrypt: Decrypt using matrix cipher (symmetric operation)
- Save PDF: Write decrypted PDF to output file
- Go 1.16 or higher
- Linux, macOS, or Windows with Go installed
# Clone the repository
git clone https://github.com/NIKJOO/ShadowBox.git
cd ShadowBox
# Build the executable
go build -o shadowbox main.go
# Verify installation
./shadowbox -hIf a Makefile exists in the project:
make build./shadowbox -mode <embed|extract> -mp4 <file> -pdf <file> -output <file> -password <pass>Embed a secret PDF into an MP4 carrier file:
./shadowbox \
-mode embed \
-mp4 carrier.mp4 \
-pdf secret.pdf \
-output embedded.mp4 \
-password "MySecurePassword123!"Parameters:
-mode embed: Activate embed mode-mp4 <file>: Path to carrier MP4 video-pdf <file>: Path to PDF to hide-output <file>: Path to save embedded MP4-password <pass>: Encryption password (remember this for extraction!)
Output:
- Embedded MP4 file with encrypted PDF hidden in mdat box
- Video remains playable in standard media players
- Original video functionality preserved
Extract and decrypt the hidden PDF from an embedded MP4:
./shadowbox \
-mode extract \
-mp4 embedded.mp4 \
-output recovered.pdf \
-password "MySecurePassword123!"Parameters:
-mode extract: Activate extract mode-mp4 <file>: Path to embedded MP4 file-output <file>: Path to save recovered PDF-password <pass>: Encryption password (must match embedding password)
Output:
- Decrypted PDF file
- Prints original mdat payload size for verification
The core encryption mechanism uses a 4×4 matrix-based stream cipher:
State Matrix (4×4): Transformation Matrix A (4×4):
[s00 s01 s02 s03] [2 3 1 1]
[s10 s11 s12 s13] [1 2 3 1]
[s20 s21 s22 s23] × [1 1 2 3]
[s30 s31 s32 s33] [3 1 1 2]
Encryption Flow:
- Initialize state matrix from 32-byte derived key
- For each 16-byte block:
- Extract keystream from state matrix (row-major)
- XOR plaintext with keystream
- Update state:
state = (state × A) mod 256
- Repeat until all data encrypted
Properties:
- Symmetric: Encryption and decryption use identical XOR operation
- Invertible: Matrix A is invertible mod 256 for diffusion
- Stream-based: Continuous state evolution across blocks
- Efficient: Single matrix multiplication per block
MP4 files use box-based hierarchical structure:
MP4 File
├── ftyp (File Type Box)
├── moov (Movie Box - metadata)
│ ├── mvhd
│ ├── trak
│ └── ...
└── mdat (Media Data Box) ← Hidden data embedded here
├── Original Video/Audio Data
├── Magic Marker: "MPDP"
├── Original Payload Size (8 bytes)
├── Encrypted PDF Size (8 bytes)
└── Encrypted PDF Data
Why mdat?
- Contains raw media samples
- Large enough to accommodate additional data
- Modification doesn't affect media playback structure
- Magic marker enables safe extraction verification
PBKDF2(password, salt, iterations=4096, length=32, hash=SHA256)
Salt: "MatrixEncryptionSalt" (fixed)
Output: 32-byte encryption key- Value:
"MPDP"(4 bytes) - Purpose: Identify encrypted PDF location in mdat
- Searched: Using
LastIndex()from end of payload - Format:
[MPDP][OrigPayloadSize:8][PDFSize:8][EncryptedPDF:N]
Standard Box (size < 4GB):
[Size:4 bytes][Type:4 bytes][Data:variable]
Extended Box (size ≥ 4GB):
[0xFFFFFFFF:4 bytes][Type:4 bytes][ExtendedSize:8 bytes][Data:variable]
# Create embedded video
./shadowbox -mode embed \
-mp4 vacation.mp4 \
-pdf confidential.pdf \
-output vacation_secure.mp4 \
-password "VerySecure123!"
# Later, extract the PDF
./shadowbox -mode extract \
-mp4 vacation_secure.mp4 \
-output recovered_confidential.pdf \
-password "VerySecure123!"# Embed multiple documents by doing separate embeds
# (Each new embed appends to mdat, last one is extracted)
./shadowbox -mode embed \
-mp4 base_video.mp4 \
-pdf contract.pdf \
-output temp1.mp4 \
-password "SecurePass123"
./shadowbox -mode embed \
-mp4 temp1.mp4 \
-pdf invoice.pdf \
-output shared_video.mp4 \
-password "SecurePass123"# Generate random password
PASSWORD=$(openssl rand -base64 32)
./shadowbox -mode embed \
-mp4 carrier.mp4 \
-pdf secret.pdf \
-output embedded.mp4 \
-password "$PASSWORD"
# Store password securely, then extract
./shadowbox -mode extract \
-mp4 embedded.mp4 \
-output recovered.pdf \
-password "$PASSWORD"ShadowBox/
├── main.go # Main application code
├── README.md # This file
├── LICENSE # Project license
└── .gitignore # Git ignore rules
- Matrix Cipher:
NewMatrixCipher(),XORStream()- Encryption/decryption logic - MP4 Parsing:
findMdat(),makeBoxHeader()- MP4 box manipulation - Core Operations:
embedPDF(),extractPDF()- Main workflows - CLI:
main()- Command-line interface
go build -o shadowbox main.gogo test -v ./...# Build for Linux
GOOS=linux GOARCH=amd64 go build -o shadowbox-linux main.go
# Build for macOS
GOOS=darwin GOARCH=amd64 go build -o shadowbox-macos main.go
# Build for Windows
GOOS=windows GOARCH=amd64 go build -o shadowbox.exe main.go- Ensure the MP4 file is valid and contains media data
- Try with a different MP4 file
- Verify the file isn't corrupted
"hidden PDF not found (magic marker missing)"
- Ensure you're using the correct embedded MP4 file
- Verify the file wasn't modified after embedding
- Check that extraction is from the correct file
- Verify the password is identical to the one used for embedding
- Passwords are case-sensitive
- Check for extra spaces or special character issues
- MP4 file may be corrupted or incomplete
- Try with a different MP4 file
- Ensure full file was transferred if downloaded
Contributions are welcome! Areas for improvement:
- Add unit tests for cipher and MP4 parsing
- Implement authenticated encryption
- Add randomized salt support with header
- Support for multiple embedded PDFs
- GUI interface
- Performance optimizations
- Additional steganography techniques
How to contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the GNU License.
This tool is provided for educational and authorized use only. Users are responsible for ensuring they have permission to embed data in files they use as carriers. The authors are not responsible for misuse of this tool.
NIMA NIKJOO
Questions or suggestions? Open an issue or start a discussion.
