StegCrypt is a Flask-based web application for hiding and extracting secret messages inside PNG images. It combines authenticated encryption, payload compression, and pseudo-random LSB steganography in a modular Python architecture.
StegCrypt is designed as a portfolio-ready security project with a clear separation between Flask routes, application services, cryptography, steganography, validation, and presentation.
- AES-256-GCM authenticated encryption
- PBKDF2-HMAC-SHA256 key derivation with random salt
- zlib compression before encryption
- Pseudo-random LSB embedding based on key-derived seed
- PNG RGB/RGBA validation with capacity checks
- Bootstrap 5 UI with drag and drop upload, preview, password strength meter, dark mode, copy actions, and toast notifications
- Automated pytest coverage for crypto and steganography flows
flowchart TD
A[Flask Route] --> B[Service Layer]
B --> C[Validators]
B --> D[Crypto Module]
B --> E[Steganography Module]
B --> F[Filesystem]
C --> G[PNG Validation]
D --> H[AES-256-GCM + PBKDF2]
E --> I[Pseudo-random LSB]
flowchart TD
A[Plaintext] --> B[zlib Compress]
B --> C[PBKDF2 Key Derivation]
C --> D[AES-256-GCM Encrypt]
D --> E[Versioned Payload + Salt + Nonce]
E --> F[Base64 Encode]
F --> G[Embed into PNG with pseudo-random LSB]
flowchart TD
A[Stego PNG] --> B[Extract Base64 Payload]
B --> C[Parse Versioned Header]
C --> D[PBKDF2 Key Derivation]
D --> E[AES-256-GCM Decrypt]
E --> F[zlib Decompress]
F --> G[Plaintext]
stegcrypt/
├── app.py
├── config.py
├── crypto/
├── services/
├── steganography/
├── validators/
├── static/
├── templates/
├── tests/
├── requirements.txt
└── README.md
- No hardcoded secret key in source code
- No hardcoded IV or nonce values
- AES-256-GCM for confidentiality and integrity
- 96-bit random nonce generated per encryption
- Random salt for every key derivation
- Versioned payload format with magic headers
- PNG-only upload validation
- Image format and mode validation
- Upload size limits
- User-safe error messages without stack traces
- Legacy AES-CBC payload compatibility for older images
- JPEG is intentionally not supported for embedding because it is lossy.
- Very small images may not have enough capacity for larger payloads.
- Pseudo-random LSB improves obfuscation, but it is still not equivalent to full cryptographic secrecy.
- Copy actions and theme toggling depend on browser clipboard support and JavaScript.
- Add PSNR and MSE quality metrics for stego output
- Export metadata JSON for encoded payloads
- Add password generator and salt viewer
- Add embedding and extraction timing metrics in the UI
- Add route-level CSRF protection and stronger request throttling
- Add a proper download token flow for generated images
- Split the app into an application factory pattern for multi-environment deployment
- Python 3.10+
- pip
git clone https://github.com/gbennnn/stegcrypt.git
cd stegcrypt
pip install -r requirements.txtpython app.pyThe app runs locally at http://127.0.0.1:5000/.
- Open the Encrypt page.
- Upload a PNG image.
- Enter your secret message.
- Enter a password.
- Download the encoded image after processing.
- Open the Decrypt page.
- Upload a StegCrypt-encoded PNG image.
- Enter the same password.
- View or copy the decrypted message.
Run the automated test suite with:
python -m pytest tests -qThe current suite covers:
- Key derivation
- AES encryption and decryption
- Compression and decompression behavior
- Legacy payload compatibility
- Steganography embed and extract round-trips
- Capacity limits
- Invalid image handling
- Wrong password and corrupted payload cases
- Python
- Flask
- cryptography
- Pillow
- pytest
- Bootstrap 5
This project is intended for educational and legitimate privacy use only. Do not use it to conceal illegal content or evade security controls.