- README.md: Add v4.0.1 to version history - API.md: Update title and version in examples to v4.0.1 - CLI.md: Update title to v4.0.1 - WEB_UI.md: Update to v4.0.1, document channel key dropdown and LED indicators 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
31 KiB
Stegasoo Web UI Documentation (v4.0.1)
Complete guide for the Stegasoo web-based steganography interface.
Table of Contents
- Overview
- What's New in v4.0.1
- Installation & Setup
- Pages & Features
- Embedding Modes
- User Interface Guide
- Workflow Examples
- Security Features
- Configuration
- Troubleshooting
- Mobile Support
Overview
The Stegasoo Web UI provides a user-friendly browser-based interface for:
- Generating secure credentials (passphrase, PINs, RSA keys)
- Encoding secret messages or files into images
- Decoding hidden messages or files from images
- Learning about the security model
Built with Flask, Bootstrap 5, and a modern dark theme.
Features
- ✅ Drag-and-drop file uploads
- ✅ Image previews with scan animations
- ✅ Native sharing (Web Share API)
- ✅ Responsive design (mobile-friendly)
- ✅ Password-protected RSA key downloads
- ✅ Real-time entropy calculations
- ✅ Automatic file cleanup
- ✅ DCT steganography mode - Now the default for social media resilience
- ✅ Color mode selection - Preserve carrier colors
- ✅ File embedding - Hide files, not just text
- ✅ QR code RSA keys - Scan to import keys
- ✅ v3.3.0: Streamlined UI - Compact mode selection, improved form flow
What's New in v4.0.1
Version 4.0.1 adds channel key support and UI improvements:
| Feature | Description |
|---|---|
| Channel keys | 256-bit keys for deployment/group isolation |
| Channel dropdown | Select channel mode (Auto/Public/Custom) |
| LED indicators | Visual status indicators for form fields |
| Key capsule styling | Improved RSA key display |
| Streamlined layout | PIN + Channel key in same row |
Key benefits:
- ✅ Channel key isolation - Different teams/deployments can't read each other's messages
- ✅ Dropdown selection for channel mode instead of radio buttons
- ✅ Visual LED indicators show field status
- ✅ Cleaner form layout with improved spacing
- ✅ Backward compatible - public mode works without channel key
Installation & Setup
From PyPI
pip install stegasoo[web]
This automatically installs DCT dependencies (scipy) for full functionality.
From Source
git clone https://github.com/example/stegasoo.git
cd stegasoo
pip install -e ".[web]"
Running the Server
Development:
cd frontends/web
python app.py
Server starts at http://localhost:5000
Production with Gunicorn:
cd frontends/web
gunicorn --bind 0.0.0.0:5000 --workers 2 --threads 4 --timeout 60 app:app
Docker:
docker-compose up web
First-Time Setup
- Navigate to http://localhost:5000
- Click "Generate" to create your credentials
- Memorize your passphrase and PIN
- Share credentials securely with your communication partner
Pages & Features
Home Page
URL: /
The landing page introduces Stegasoo and provides quick access to all features.
Main Actions
| Card | Description | Link |
|---|---|---|
| Encode Message | Hide a secret in an image | /encode |
| Decode Message | Extract a hidden message | /decode |
| Generate Keys | Create new credentials | /generate |
"How It Works" Section
Explains the three key components:
- Reference Photo - Shared secret image
- Passphrase - Your secret phrase (v3.2.0: same every time!)
- Static PIN - Same every day
Generate Credentials
URL: /generate
Create a new set of credentials for steganography operations.
Configuration Options
| Option | Range | Default | Description |
|---|---|---|---|
| Words per passphrase | 3-12 | 4 | BIP-39 words in passphrase |
| Use PIN | on/off | on | Generate a numeric PIN |
| PIN length | 6-9 | 6 | Digits in the PIN |
| Use RSA Key | on/off | off | Generate an RSA key pair |
| RSA key size | 2048/3072/4096 | 2048 | Key size in bits |
Entropy Calculator
The UI displays real-time entropy calculations:
Estimated entropy: ~63 bits
[=============> ] Good for most use cases
• Reference photo adds ~80-256 bits more
Generated Output (v3.2.0)
After clicking "Generate Credentials":
Static PIN (if enabled):
┌─────────────────────┐
│ 8 4 7 2 9 3 │
└─────────────────────┘
Use this 6-digit PIN every time
Passphrase (v3.2.0: single passphrase, no daily rotation):
┌─────────────────────────────────────────┐
│ abandon ability able about │
│ │
│ Use this passphrase to encode and │
│ decode messages - no date needed! │
└─────────────────────────────────────────┘
RSA Key (if enabled):
- Copy to clipboard button
- Download as password-protected .pem file
- Download as QR code image
Security Summary:
Passphrase entropy: 44 bits (4 words)
PIN entropy: 19 bits
RSA entropy: 128 bits
─────────────────────────────
Total: 191 bits
+ reference photo (~80-256 bits) = 271+ bits combined
RSA Key Download
- Click "Download as .pem"
- Enter a password (minimum 8 characters)
- Click "Download Protected Key"
- Save the file securely
- Share with your communication partner through a secure channel
RSA Key QR Code
For easier sharing, you can also:
- Click "Download QR Code"
- Save the QR code image
- Your partner can scan it to import the key
Encode Message
URL: /encode
Hide a secret message or file inside an image.
Form Flow (v3.3.0)
The encode form follows a logical flow:
- Load Images - Reference photo and carrier image
- View Capacity - Shows available capacity for DCT and LSB modes
- Select Mode - DCT (default) or LSB with inline tooltips
- Enter Payload - Text message or file
- Add Security - Passphrase, PIN, and/or RSA key
Input Fields
| Field | Type | Required | Description |
|---|---|---|---|
| Reference Photo | Image file | ✓ | Your shared secret photo |
| Carrier Image | Image file | ✓ | Image to hide message in |
| Embedding Mode | Toggle | ✓ | DCT (default) or LSB |
| Payload Type | Toggle | ✓ | Text message or file |
| Secret Message | Text | * | Message to hide (max 50KB) |
| File to Embed | File | * | File to hide (max 2MB) |
| Passphrase | Text | ✓ | Your passphrase |
| PIN | Number | ** | Your static PIN |
| RSA Key | .pem file | ** | Your shared RSA key |
| RSA Key QR | Image file | ** | QR code containing RSA key |
| RSA Key Password | Password | Password for encrypted key |
* One of message or file required. ** At least one security factor (PIN or RSA Key) required.
Embedding Mode Selection (v3.3.0)
The mode selector is now a compact inline toggle:
┌────────────────────────────────────────────────────────────┐
│ ◉ 🔊 DCT · Social Media ⓘ │ ○ ⊞ LSB · Email & Files ⓘ │
└────────────────────────────────────────────────────────────┘
- DCT - Default, best for social media sharing
- LSB - Higher capacity, for lossless channels
- ⓘ - Hover for details (capacity, output format, etc.)
DCT Options
When DCT mode is selected, additional options appear:
| Option | Values | Default | Description |
|---|---|---|---|
| Output Format | PNG / JPEG | JPEG | Output image format |
| Color Mode | Color / Grayscale | Color | Carrier color handling |
Drag-and-Drop Upload
Both image upload zones support:
- Click to browse
- Drag and drop files
- Instant image preview with scan animation
- Status indicators ("Hash Acquired", "Carrier Loaded")
Capacity Info Panel
After loading a carrier image, a capacity panel appears:
┌─────────────────────────────────────────────────────────┐
│ 📏 Carrier: 1920 × 1080 (2.1 MP) DCT: 150 KB LSB: 750 KB │
└─────────────────────────────────────────────────────────┘
Character Counter
Message: [ ]
1,234 / 50,000 characters 2%
Shows warning at 80% capacity.
Encoding Process
- Upload reference photo and carrier image
- View capacity info panel
- Select embedding mode (DCT default)
- Choose payload type and enter content
- Enter passphrase and security factors
- Click "Encode Message"
- Wait for processing (shows spinner)
- Redirected to result page
Result Page
URL: /encode/result/<file_id>
After successful encoding:
┌────────────────────────────────────────┐
│ ✓ Message Encoded Successfully! │
│ │
│ 📄 a1b2c3d4.png │
│ Your secret is hidden │
│ in this image │
│ │
│ Mode: DCT (Color, JPEG) │
│ Capacity used: 45.2% │
│ │
│ [ Download Image ] │
│ [ Share Image ] │
│ │
│ ⚠️ File expires in 5 minutes. │
│ Download or share now. │
│ │
│ [ Encode Another Message ] │
└────────────────────────────────────────┘
Share Options:
-
Native Share (mobile/supported browsers):
- Uses Web Share API
- Opens system share sheet
- Can share directly to apps
-
Fallback Share (desktop):
- Email link
- Telegram link
- WhatsApp link
- Copy link to clipboard
Decode Message
URL: /decode
Extract a hidden message or file from a stego image.
Input Fields
| Field | Type | Required | Description |
|---|---|---|---|
| Reference Photo | Image file | ✓ | Same photo used for encoding |
| Stego Image | Image file | ✓ | Image containing hidden message |
| Passphrase | Text | ✓ | Same passphrase used for encoding |
| PIN | Number | * | Same PIN used for encoding |
| RSA Key | .pem file | * | Same RSA key used for encoding |
| RSA Key QR | Image file | * | QR code containing RSA key |
| RSA Key Password | Password | Password for encrypted key |
* Must match security factors used during encoding.
Automatic Mode Detection
The decoder automatically detects whether a stego image uses LSB or DCT mode. You don't need to specify the mode manually—it just works!
Decoding Process (v3.2.0 Simplified)
- Upload the same reference photo
- Upload the received stego image
- Enter your passphrase (no date needed!)
- Enter your PIN and/or RSA key
- Click "Decode Message"
- View decoded message or download decoded file
Successful Decode (Text)
┌────────────────────────────────────────┐
│ ✓ Message Decrypted Successfully! │
│ │
│ Decoded Message: │
│ ┌──────────────────────────────────┐ │
│ │ Meet at midnight. The package │ │
│ │ will be under the bridge. │ │
│ └──────────────────────────────────┘ │
│ │
│ [ Decode Another Message ] │
└────────────────────────────────────────┘
Successful Decode (File)
┌────────────────────────────────────────┐
│ ✓ File Extracted Successfully! │
│ │
│ 📄 secret_document.pdf │
│ Size: 245 KB │
│ Type: application/pdf │
│ │
│ [ Download File ] │
│ │
│ ⚠️ File expires in 5 minutes. │
│ │
│ [ Decode Another Message ] │
└────────────────────────────────────────┘
Troubleshooting Tips
If decryption fails:
- Check passphrase - Must be exact match (case-sensitive)
- Same reference photo - Must be identical file
- Correct PIN/RSA - Match what was used for encoding
- Image integrity - Ensure no resizing/recompression (LSB mode)
About Page
URL: /about
Information about the Stegasoo project, security model, and credits.
Includes:
- Version information (v3.3.0)
- Recent UI improvements
- Security model overview
- Dependency status (Argon2, QR code support)
Embedding Modes
Stegasoo offers two steganography algorithms, each with different trade-offs.
DCT Mode (Default)
Discrete Cosine Transform embedding hides data in frequency domain coefficients. This is now the default mode when scipy is available.
| Aspect | Details |
|---|---|
| Capacity | ~0.5 bits/pixel (~75 KB/MP) |
| Output Formats | PNG or JPEG |
| Resilience | ✅ Survives JPEG recompression |
| Best For | Social media, messaging apps |
When to use DCT:
- Sharing via social media (Instagram, WhatsApp, Telegram)
- When image may be recompressed
- When stealth is important
- Smaller messages that fit in reduced capacity
DCT Output Formats
| Format | Pros | Cons |
|---|---|---|
| JPEG | Native format, natural, smaller, resilient | Slightly lower capacity |
| PNG | Lossless, predictable | Larger file |
DCT Color Modes
| Mode | Description | Use Case |
|---|---|---|
| Color | Embeds in luminance (Y), preserves chrominance | Most images, photos |
| Grayscale | Converts to grayscale before embedding | Black & white images |
LSB Mode
Least Significant Bit embedding modifies the least significant bits of pixel values.
| Aspect | Details |
|---|---|
| Capacity | ~3 bits/pixel (~375 KB/MP) |
| Output Format | PNG only (lossless required) |
| Resilience | ❌ Destroyed by JPEG compression |
| Best For | Maximum capacity, controlled sharing |
When to use LSB:
- Sharing via lossless channels (email attachment, file transfer, cloud storage)
- Maximum message capacity needed
- Recipient won't modify/recompress the image
Capacity Comparison
For a 1920×1080 image (~2 MP):
| Mode | Approximate Capacity |
|---|---|
| LSB (PNG) | ~750 KB |
| DCT (PNG, Color) | ~150 KB |
| DCT (JPEG) | ~150 KB |
Choosing the Right Mode
┌─────────────────────────────────────────────────────────────┐
│ Mode Selection Guide │
├─────────────────────────────────────────────────────────────┤
│ │
│ Sharing via social media / messaging app? │
│ │ │
│ ┌───────┴───────┐ │
│ ▼ ▼ │
│ YES NO │
│ │ │ │
│ ▼ ▼ │
│ Use DCT Need maximum capacity? │
│ (default) │ │
│ ┌───────┴───────┐ │
│ ▼ ▼ │
│ YES NO │
│ │ │ │
│ ▼ ▼ │
│ Use LSB Use DCT │
│ (default) │
│ │
└─────────────────────────────────────────────────────────────┘
User Interface Guide
Layout Structure
┌──────────────────────────────────────────────────────────────┐
│ 🦕 Stegasoo [Encode] [Decode] [Generate] │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Page Content │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Upload Zone │ │ Upload Zone │ │ │
│ │ │ (Reference) │ │ (Carrier) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ Passphrase: [________________________] │ │
│ │ PIN: [____________] │ │
│ │ │ │
│ │ [Advanced Options ▼] │ │
│ │ ┌────────────────────────────────────────────┐ │ │
│ │ │ Embedding Mode: [LSB ▼] │ │ │
│ │ │ Output Format: [PNG ▼] (DCT only) │ │ │
│ │ │ Color Mode: [Color ▼] (DCT only) │ │ │
│ │ └────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ [ Encode Message ] │ │
│ │ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
├──────────────────────────────────────────────────────────────┤
│ Footer │
└──────────────────────────────────────────────────────────────┘
Color Scheme
| Element | Color | Purpose |
|---|---|---|
| Background | Dark gradient | Reduce eye strain |
| Cards | Semi-transparent | Visual hierarchy |
| Headers | Purple gradient | Brand identity |
| Success | Green | Positive actions |
| Warning | Yellow | Caution messages |
| Error | Red | Error states |
Form Validation
- Real-time validation feedback
- Clear error messages in alerts
- Required field indicators
- Input constraints (max length, format)
- Passphrase word count validation (v3.2.0)
Loading States
During long operations:
- Button shows spinner
- Button text changes (e.g., "Encoding...")
- Button is disabled to prevent double-submit
Flash Messages
┌──────────────────────────────────────────────┐
│ ✓ Credentials Generated! [×] │
└──────────────────────────────────────────────┘
Types:
- Success (green) - Operation completed
- Error (red) - Operation failed
- Warning (yellow) - Caution needed (e.g., short passphrase)
Workflow Examples
First-Time Setup (Both Parties)
Party A:
- Go to
/generate - Configure: PIN ✓, 4 words, 6 digits
- Click "Generate Credentials"
- Write down passphrase and PIN on paper
- Memorize over the next few days
- Destroy the paper
Share with Party B (in person or secure channel):
- The passphrase (just one phrase now!)
- The PIN
- The reference photo file (if not already shared)
Sending a Secret Message (LSB - Default)
- Go to
/encode - Upload your shared reference photo
- Upload any carrier image (meme, vacation photo, etc.)
- Type your secret message
- Enter your passphrase
- Enter your PIN
- Click "Encode Message"
- Download or share the resulting image
- Send via any channel (email, file transfer)
Sending with DCT Mode
- Go to
/encode - Upload your shared reference photo
- Upload carrier image
- Type your secret message
- Enter your passphrase and PIN
- Expand "Advanced Options"
- Select "DCT" embedding mode
- Select "JPEG" output format (optional)
- Click "Encode Message"
- Download and share
Receiving a Secret Message (v3.2.0 Simplified)
- Receive the stego image through any channel
- Go to
/decode - Upload the same reference photo
- Upload the received stego image
- Enter your passphrase (no date needed!)
- Enter your PIN
- Click "Decode Message"
- Read the secret message or download the file
Embedding a File
- Go to
/encode - Upload reference photo and carrier image
- Select "File" as payload type
- Upload the file to embed (max 2MB)
- Enter passphrase and PIN
- Click "Encode Message"
- Download the stego image
Extracting a File
- Go to
/decode - Upload reference photo and stego image
- Enter passphrase and PIN
- Click "Decode Message"
- Click "Download File" to save the extracted file
Changing Credentials
To rotate to new credentials:
- Both parties generate new credentials together
- Agree on a cutover date
- Messages encoded before cutover use old credentials
- Messages encoded after cutover use new credentials
Security Features
Client-Side Security
| Feature | Implementation |
|---|---|
| No credential storage | Nothing saved in browser |
| Automatic cleanup | Files deleted after 5 minutes |
| HTTPS support | Configure at server level |
Server-Side Security
| Feature | Implementation |
|---|---|
| Memory-hard KDF | Argon2id (256MB RAM) |
| Authenticated encryption | AES-256-GCM |
| Random salt | Per-message salt |
| Temporary storage | In-memory, auto-expiring |
| Input validation | All inputs validated |
| File size limits | 5MB max upload |
File Security
| Aspect | Protection |
|---|---|
| Upload location | /tmp/stego_uploads (Docker) |
| Storage duration | 5 minutes maximum |
| Access control | Random 16-byte file ID |
| Cleanup | Automatic + manual |
Embedding Mode Security
| Mode | Security Consideration |
|---|---|
| LSB | Full capacity, but fragile to modification |
| DCT | Lower capacity, frequency domain hiding |
Both modes use the same strong encryption (AES-256-GCM with Argon2id key derivation).
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
FLASK_ENV |
production | Flask environment |
PYTHONPATH |
- | Include src/ for development |
Application Limits
| Limit | Value | Config Location |
|---|---|---|
| Max file upload | 5 MB | app.config['MAX_CONTENT_LENGTH'] |
| File expiry | 5 minutes | TEMP_FILE_EXPIRY |
| Max image pixels | 4 MP | stegasoo.constants |
| Max message size | 50 KB | stegasoo.constants |
| Max file payload | 2 MB | stegasoo.constants |
| PIN length | 6-9 digits | stegasoo.constants |
| Passphrase words | 3-12 | stegasoo.constants |
Production Deployment
With Gunicorn:
gunicorn \
--bind 0.0.0.0:5000 \
--workers 2 \
--threads 4 \
--timeout 60 \
app:app
Worker Calculation:
- Each encode/decode uses ~256MB RAM (Argon2) + ~100MB for scipy (DCT mode)
- Formula:
workers = (available_RAM - 512MB) / 350MB
With Nginx (reverse proxy):
server {
listen 80;
server_name stegasoo.example.com;
client_max_body_size 10M;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 120s;
}
}
With Docker Compose:
services:
web:
build:
context: .
target: web
ports:
- "5000:5000"
deploy:
resources:
limits:
memory: 768M
reservations:
memory: 384M
Troubleshooting
Common Issues
"Decryption failed"
Causes:
- Wrong passphrase
- Wrong PIN
- Different reference photo
- Stego image was modified
Solutions:
- Verify exact passphrase (case-sensitive)
- Verify you're using the original reference photo
- Ensure the stego image wasn't resized/recompressed (LSB mode)
"Invalid or missing Stegasoo header"
Causes:
- Image was heavily recompressed
- Wrong credentials
- Corrupted during transfer
Solutions:
- Verify credentials match
- Try obtaining original file
- If using DCT mode, some modification is expected to work
"Carrier image too small"
Cause: Message too large for carrier capacity
Solutions:
- Use a larger carrier image (more pixels)
- Shorten the message
- Use LSB mode for more capacity
"Passphrase should have at least 4 words"
Cause: Passphrase too short (v3.2.0 warning)
Solutions:
- Use a longer passphrase for better security
- Can still proceed with shorter passphrase (warning only)
"You must provide at least a PIN or RSA Key"
Cause: No security factor selected
Solution: Enter a PIN and/or upload an RSA key
Upload fails silently
Causes:
- File too large (>5MB)
- Invalid file type
- Browser issue
Solutions:
- Reduce file size
- Use PNG, JPG, or BMP formats
- Try a different browser
RSA key password error
Causes:
- Wrong password
- Unencrypted key with password provided
- Corrupted key file
Solutions:
- Verify the correct password
- If key is unencrypted, leave password blank
- Re-download or regenerate the key
DCT mode shows "requires scipy"
Cause: scipy library not installed
Solution:
pip install scipy
# Or rebuild Docker image
docker-compose build --no-cache
Browser Compatibility
| Browser | Status | Notes |
|---|---|---|
| Chrome 80+ | ✓ Full | Web Share API supported |
| Firefox 80+ | ✓ Full | Limited Web Share |
| Safari 14+ | ✓ Full | Web Share on iOS |
| Edge 80+ | ✓ Full | Web Share API supported |
| IE 11 | ✗ None | Not supported |
Performance Issues
Slow encoding/decoding:
- Normal: Argon2 is intentionally slow (security feature)
- DCT mode adds ~1-2 seconds for transform operations
- Expected time: 3-7 seconds per operation
High memory usage:
- Normal: Argon2 requires 256MB RAM
- DCT mode adds scipy memory overhead (~100MB)
- Configure worker count based on available RAM
Mobile Support
Responsive Design
The UI adapts to mobile screens:
- Single-column layout on small screens
- Touch-friendly buttons (48px minimum)
- Readable text without zooming
- Scrollable tables
- Collapsible "Advanced Options" for cleaner mobile view
Mobile-Specific Features
Native Sharing: On supported mobile browsers, the "Share Image" button opens the native share sheet, allowing you to share directly to:
- Messaging apps (iMessage, WhatsApp, Telegram)
- Social media (Instagram, Twitter)
- Other installed apps
Camera Upload: File input accepts camera capture:
- Take a new photo as reference
- Capture carrier image directly
PWA Support (Future)
The web app can be added to home screen on mobile devices for quick access.
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Tab |
Navigate between fields |
Enter |
Submit form (when focused) |
Esc |
Close modal/alert |
Accessibility
| Feature | Implementation |
|---|---|
| Screen readers | ARIA labels on interactive elements |
| Keyboard navigation | Full tab support |
| Color contrast | WCAG AA compliant |
| Focus indicators | Visible focus rings |
| Form labels | All inputs labeled |
See Also
- CLI Documentation - Command-line interface
- API Documentation - REST API reference
- Web Frontend Update Summary - Migration details
- README - Project overview