Moved all docs to root.
This commit is contained in:
882
frontends/API.md
882
frontends/API.md
@@ -1,882 +0,0 @@
|
||||
# Stegasoo REST API Documentation (v4.0.1)
|
||||
|
||||
Complete REST API reference for Stegasoo steganography operations.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [What's New in v4.0.0](#whats-new-in-v400)
|
||||
- [Installation](#installation)
|
||||
- [Base URL](#base-url)
|
||||
- [Endpoints](#endpoints)
|
||||
- [GET /](#get--status)
|
||||
- [GET /modes](#get-modes)
|
||||
- [GET /channel/status](#get-channelstatus)
|
||||
- [POST /channel/generate](#post-channelgenerate)
|
||||
- [POST /channel/set](#post-channelset)
|
||||
- [DELETE /channel](#delete-channel)
|
||||
- [POST /generate](#post-generate)
|
||||
- [POST /encode](#post-encode-json)
|
||||
- [POST /encode/file](#post-encodefile)
|
||||
- [POST /encode/multipart](#post-encodemultipart)
|
||||
- [POST /decode](#post-decode-json)
|
||||
- [POST /decode/multipart](#post-decodemultipart)
|
||||
- [POST /compare](#post-compare)
|
||||
- [POST /will-fit](#post-will-fit)
|
||||
- [POST /image/info](#post-imageinfo)
|
||||
- [Channel Keys](#channel-keys)
|
||||
- [Data Models](#data-models)
|
||||
- [Error Handling](#error-handling)
|
||||
- [Code Examples](#code-examples)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Stegasoo REST API provides programmatic access to all steganography operations:
|
||||
|
||||
- **Generate** credentials (passphrase, PINs, RSA keys)
|
||||
- **Encode** messages or files into images (LSB or DCT mode)
|
||||
- **Decode** messages or files from images (auto-detects mode)
|
||||
- **Channel keys** for deployment/group isolation (v4.0.0)
|
||||
- **Analyze** image capacity and compare modes
|
||||
|
||||
The API supports both JSON (base64-encoded images) and multipart form data (direct file uploads).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v4.0.0
|
||||
|
||||
Version 4.0.0 adds **channel key** support for deployment/group isolation:
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| Channel keys | 256-bit keys that isolate message groups |
|
||||
| New endpoints | `/channel/status`, `/channel/generate`, `/channel/set`, `DELETE /channel` |
|
||||
| Encode/decode param | `channel_key` parameter on all encode/decode endpoints |
|
||||
| Response headers | `X-Stegasoo-Channel-Mode` and `X-Stegasoo-Channel-Fingerprint` |
|
||||
|
||||
**Key benefits:**
|
||||
- ✅ Isolate messages between teams, deployments, or groups
|
||||
- ✅ Same credentials can't decode messages from different channels
|
||||
- ✅ Backward compatible (public mode = no channel key)
|
||||
|
||||
**Breaking change:** v4.0.0 messages (with channel key) cannot be decoded by v3.x installations.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### From PyPI
|
||||
|
||||
```bash
|
||||
pip install stegasoo[api]
|
||||
```
|
||||
|
||||
### Running the Server
|
||||
|
||||
**Development:**
|
||||
```bash
|
||||
cd frontends/api
|
||||
python main.py
|
||||
```
|
||||
|
||||
**Production:**
|
||||
```bash
|
||||
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
|
||||
```
|
||||
|
||||
**Docker with channel key:**
|
||||
```bash
|
||||
STEGASOO_CHANNEL_KEY=XXXX-XXXX-... docker-compose up api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Base URL
|
||||
|
||||
| Environment | URL |
|
||||
|-------------|-----|
|
||||
| Local Development | `http://localhost:8000` |
|
||||
| Docker | `http://localhost:8000` |
|
||||
| Production | Configure as needed |
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
### GET / (Status)
|
||||
|
||||
Check API status and configuration.
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "4.0.1",
|
||||
"has_argon2": true,
|
||||
"has_qrcode_read": true,
|
||||
"has_dct": true,
|
||||
"max_payload_kb": 500,
|
||||
"available_modes": ["lsb", "dct"],
|
||||
"dct_features": {
|
||||
"output_formats": ["png", "jpeg"],
|
||||
"color_modes": ["grayscale", "color"]
|
||||
},
|
||||
"channel": {
|
||||
"mode": "private",
|
||||
"configured": true,
|
||||
"fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456",
|
||||
"source": "~/.stegasoo/channel.key"
|
||||
},
|
||||
"breaking_changes": {
|
||||
"v4_channel_key": "Messages encoded with channel key require same key to decode",
|
||||
"format_version": 5,
|
||||
"backward_compatible": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### GET /modes
|
||||
|
||||
Get available embedding modes and channel status.
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"lsb": {
|
||||
"available": true,
|
||||
"name": "Spatial LSB",
|
||||
"description": "Embed in pixel LSBs, outputs PNG/BMP",
|
||||
"output_format": "PNG (color)",
|
||||
"capacity_ratio": "100%"
|
||||
},
|
||||
"dct": {
|
||||
"available": true,
|
||||
"name": "DCT Domain",
|
||||
"output_formats": ["png", "jpeg"],
|
||||
"color_modes": ["grayscale", "color"],
|
||||
"capacity_ratio": "~20% of LSB",
|
||||
"requires": "scipy"
|
||||
},
|
||||
"channel": {
|
||||
"mode": "private",
|
||||
"configured": true,
|
||||
"fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### GET /channel/status
|
||||
|
||||
Get current channel key status. **New in v4.0.0.**
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `reveal` | boolean | `false` | Include full key in response |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "private",
|
||||
"configured": true,
|
||||
"fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456",
|
||||
"source": "~/.stegasoo/channel.key",
|
||||
"key": null
|
||||
}
|
||||
```
|
||||
|
||||
With `reveal=true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "private",
|
||||
"configured": true,
|
||||
"fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456",
|
||||
"source": "~/.stegasoo/channel.key",
|
||||
"key": "ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456"
|
||||
}
|
||||
```
|
||||
|
||||
#### cURL Example
|
||||
|
||||
```bash
|
||||
# Show status
|
||||
curl http://localhost:8000/channel/status
|
||||
|
||||
# Reveal full key
|
||||
curl "http://localhost:8000/channel/status?reveal=true"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /channel/generate
|
||||
|
||||
Generate a new channel key. **New in v4.0.0.**
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `save` | boolean | `false` | Save to user config |
|
||||
| `save_project` | boolean | `false` | Save to project config |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"key": "ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456",
|
||||
"fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456",
|
||||
"saved": true,
|
||||
"save_location": "~/.stegasoo/channel.key"
|
||||
}
|
||||
```
|
||||
|
||||
#### cURL Examples
|
||||
|
||||
```bash
|
||||
# Just generate (don't save)
|
||||
curl -X POST http://localhost:8000/channel/generate
|
||||
|
||||
# Generate and save to user config
|
||||
curl -X POST "http://localhost:8000/channel/generate?save=true"
|
||||
|
||||
# Generate and save to project config
|
||||
curl -X POST "http://localhost:8000/channel/generate?save_project=true"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /channel/set
|
||||
|
||||
Set/save a channel key to config. **New in v4.0.0.**
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"key": "ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456",
|
||||
"location": "user"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
|-------|------|---------|-------------|
|
||||
| `key` | string | required | Channel key |
|
||||
| `location` | string | `"user"` | `"user"` or `"project"` |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"location": "~/.stegasoo/channel.key",
|
||||
"fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### DELETE /channel
|
||||
|
||||
Clear channel key from config. **New in v4.0.0.**
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `location` | string | `"user"` | `"user"`, `"project"`, or `"all"` |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"mode": "public",
|
||||
"still_configured": false,
|
||||
"remaining_source": null
|
||||
}
|
||||
```
|
||||
|
||||
#### cURL Example
|
||||
|
||||
```bash
|
||||
# Clear user config
|
||||
curl -X DELETE http://localhost:8000/channel
|
||||
|
||||
# Clear project config
|
||||
curl -X DELETE "http://localhost:8000/channel?location=project"
|
||||
|
||||
# Clear all
|
||||
curl -X DELETE "http://localhost:8000/channel?location=all"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /generate
|
||||
|
||||
Generate credentials for encoding/decoding.
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"use_pin": true,
|
||||
"use_rsa": false,
|
||||
"pin_length": 6,
|
||||
"rsa_bits": 2048,
|
||||
"words_per_passphrase": 4
|
||||
}
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"passphrase": "abandon ability able about",
|
||||
"pin": "847293",
|
||||
"rsa_key_pem": null,
|
||||
"entropy": {
|
||||
"passphrase": 44,
|
||||
"pin": 19,
|
||||
"rsa": 0,
|
||||
"total": 63
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /encode (JSON)
|
||||
|
||||
Encode a text message into an image.
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Secret message here",
|
||||
"reference_photo_base64": "iVBORw0KGgo...",
|
||||
"carrier_image_base64": "iVBORw0KGgo...",
|
||||
"passphrase": "apple forest thunder mountain",
|
||||
"pin": "123456",
|
||||
"rsa_key_base64": null,
|
||||
"rsa_password": null,
|
||||
"channel_key": null,
|
||||
"embed_mode": "lsb",
|
||||
"dct_output_format": "png",
|
||||
"dct_color_mode": "grayscale"
|
||||
}
|
||||
```
|
||||
|
||||
#### Channel Key Parameter (v4.0.0)
|
||||
|
||||
| Value | Effect |
|
||||
|-------|--------|
|
||||
| `null` | Auto mode - use server-configured key |
|
||||
| `""` (empty string) | Public mode - no channel isolation |
|
||||
| `"XXXX-XXXX-..."` | Explicit key - use this specific key |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"stego_image_base64": "iVBORw0KGgo...",
|
||||
"filename": "a1b2c3d4.png",
|
||||
"capacity_used_percent": 12.4,
|
||||
"embed_mode": "lsb",
|
||||
"output_format": "png",
|
||||
"color_mode": "color",
|
||||
"channel_mode": "private",
|
||||
"channel_fingerprint": "ABCD-••••-••••-••••-••••-••••-••••-3456"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /encode/file
|
||||
|
||||
Encode a file into an image (JSON with base64).
|
||||
|
||||
Same parameters as `/encode`, plus:
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `file_data_base64` | string | ✓ | Base64-encoded file data |
|
||||
| `filename` | string | ✓ | Original filename |
|
||||
| `mime_type` | string | | MIME type |
|
||||
|
||||
---
|
||||
|
||||
### POST /encode/multipart
|
||||
|
||||
Encode using multipart form data (file uploads).
|
||||
|
||||
#### Form Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `passphrase` | string | ✓ | Passphrase |
|
||||
| `reference_photo` | file | ✓ | Reference photo |
|
||||
| `carrier` | file | ✓ | Carrier image |
|
||||
| `message` | string | * | Text message |
|
||||
| `payload_file` | file | * | Binary file to embed |
|
||||
| `pin` | string | | Static PIN |
|
||||
| `rsa_key` | file | | RSA key (.pem) |
|
||||
| `rsa_key_qr` | file | | RSA key (QR code image) |
|
||||
| `rsa_password` | string | | RSA key password |
|
||||
| `channel_key` | string | | `"auto"` (default), `"none"=public`, or explicit key |
|
||||
| `embed_mode` | string | | `"lsb"` or `"dct"` |
|
||||
| `dct_output_format` | string | | `"png"` or `"jpeg"` |
|
||||
| `dct_color_mode` | string | | `"grayscale"` or `"color"` |
|
||||
|
||||
\* Provide either `message` or `payload_file`
|
||||
|
||||
#### Channel Key in Multipart
|
||||
|
||||
For form data, the channel_key field uses strings:
|
||||
|
||||
| Value | Effect |
|
||||
|-------|--------|
|
||||
| `"auto"` | Use server config (default) |
|
||||
| `"none"` | Public mode |
|
||||
| `"XXXX-XXXX-..."` | Explicit key |
|
||||
|
||||
#### Response
|
||||
|
||||
Returns the stego image directly with headers:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: image/png
|
||||
Content-Disposition: attachment; filename=a1b2c3d4.png
|
||||
X-Stegasoo-Capacity-Percent: 12.4
|
||||
X-Stegasoo-Embed-Mode: lsb
|
||||
X-Stegasoo-Channel-Mode: private
|
||||
X-Stegasoo-Channel-Fingerprint: ABCD-••••-...-3456
|
||||
X-Stegasoo-Version: 4.0.1
|
||||
|
||||
<binary image data>
|
||||
```
|
||||
|
||||
#### cURL Examples
|
||||
|
||||
```bash
|
||||
# Encode with auto channel key (default)
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "passphrase=apple forest thunder mountain" \
|
||||
-F "pin=123456" \
|
||||
-F "message=Secret message" \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
|
||||
# Encode with explicit channel key
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "passphrase=words here" \
|
||||
-F "pin=123456" \
|
||||
-F "message=Team message" \
|
||||
-F "channel_key=ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456" \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
|
||||
# Encode in public mode (no channel isolation)
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "passphrase=words here" \
|
||||
-F "pin=123456" \
|
||||
-F "message=Public message" \
|
||||
-F "channel_key=none" \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /decode (JSON)
|
||||
|
||||
Decode a message or file from a stego image.
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"stego_image_base64": "iVBORw0KGgo...",
|
||||
"reference_photo_base64": "iVBORw0KGgo...",
|
||||
"passphrase": "apple forest thunder mountain",
|
||||
"pin": "123456",
|
||||
"rsa_key_base64": null,
|
||||
"rsa_password": null,
|
||||
"channel_key": null,
|
||||
"embed_mode": "auto"
|
||||
}
|
||||
```
|
||||
|
||||
#### Response (Text)
|
||||
|
||||
```json
|
||||
{
|
||||
"payload_type": "text",
|
||||
"message": "Secret message here",
|
||||
"file_data_base64": null,
|
||||
"filename": null,
|
||||
"mime_type": null
|
||||
}
|
||||
```
|
||||
|
||||
#### Response (File)
|
||||
|
||||
```json
|
||||
{
|
||||
"payload_type": "file",
|
||||
"message": null,
|
||||
"file_data_base64": "UEsDBBQAAAA...",
|
||||
"filename": "document.pdf",
|
||||
"mime_type": "application/pdf"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /decode/multipart
|
||||
|
||||
Decode using multipart form data.
|
||||
|
||||
#### Form Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `passphrase` | string | ✓ | Passphrase |
|
||||
| `reference_photo` | file | ✓ | Reference photo |
|
||||
| `stego_image` | file | ✓ | Stego image to decode |
|
||||
| `pin` | string | | Static PIN |
|
||||
| `rsa_key` | file | | RSA key (.pem) |
|
||||
| `rsa_key_qr` | file | | RSA key (QR code image) |
|
||||
| `rsa_password` | string | | RSA key password |
|
||||
| `channel_key` | string | | `"auto"` (default), `"none"=public`, or explicit key |
|
||||
| `embed_mode` | string | | `"auto"`, `"lsb"`, or `"dct"` |
|
||||
|
||||
---
|
||||
|
||||
## Channel Keys
|
||||
|
||||
### Overview
|
||||
|
||||
Channel keys provide **deployment/group isolation**. Messages encoded with a channel key can only be decoded with the same key.
|
||||
|
||||
### Key Format
|
||||
|
||||
```
|
||||
ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
└──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘
|
||||
8 groups of 4 alphanumeric characters (256 bits)
|
||||
```
|
||||
|
||||
### Storage Locations
|
||||
|
||||
Keys are checked in order:
|
||||
|
||||
| Priority | Location | Best For |
|
||||
|----------|----------|----------|
|
||||
| 1 | `STEGASOO_CHANNEL_KEY` env var | Docker, CI/CD |
|
||||
| 2 | `./config/channel.key` | Project-specific |
|
||||
| 3 | `~/.stegasoo/channel.key` | User default |
|
||||
|
||||
### API Parameter Values
|
||||
|
||||
#### JSON Endpoints (`/encode`, `/decode`)
|
||||
|
||||
| Value | Effect |
|
||||
|-------|--------|
|
||||
| `null` | Auto - use server config |
|
||||
| `""` | Public mode |
|
||||
| `"XXXX-..."` | Explicit key |
|
||||
|
||||
#### Multipart Endpoints (`/encode/multipart`, `/decode/multipart`)
|
||||
|
||||
| Value | Effect |
|
||||
|-------|--------|
|
||||
| `"auto"` | Use server config (default) |
|
||||
| `"none"` | Public mode |
|
||||
| `"XXXX-..."` | Explicit key |
|
||||
|
||||
### Workflow Example
|
||||
|
||||
```bash
|
||||
# 1. Generate a channel key for the team
|
||||
KEY=$(curl -s -X POST http://localhost:8000/channel/generate | jq -r '.key')
|
||||
echo "Team key: $KEY"
|
||||
|
||||
# 2. Distribute to team members (securely!)
|
||||
|
||||
# 3. Each deployment sets the key
|
||||
export STEGASOO_CHANNEL_KEY=$KEY
|
||||
|
||||
# 4. Encode - automatically uses server key
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "passphrase=team passphrase" \
|
||||
-F "pin=123456" \
|
||||
-F "message=Team secret" \
|
||||
-F "reference_photo=@ref.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
|
||||
# 5. Decode - automatically uses server key
|
||||
curl -X POST http://localhost:8000/decode/multipart \
|
||||
-F "passphrase=team passphrase" \
|
||||
-F "pin=123456" \
|
||||
-F "reference_photo=@ref.jpg" \
|
||||
-F "stego_image=@stego.png"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Models
|
||||
|
||||
### ChannelStatusResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "private",
|
||||
"configured": true,
|
||||
"fingerprint": "ABCD-••••-...-3456",
|
||||
"source": "~/.stegasoo/channel.key",
|
||||
"key": "ABCD-1234-..."
|
||||
}
|
||||
```
|
||||
|
||||
### EncodeResponse (v4.0.0)
|
||||
|
||||
```json
|
||||
{
|
||||
"stego_image_base64": "string",
|
||||
"filename": "string",
|
||||
"capacity_used_percent": 12.4,
|
||||
"embed_mode": "lsb",
|
||||
"output_format": "png",
|
||||
"color_mode": "color",
|
||||
"channel_mode": "private",
|
||||
"channel_fingerprint": "ABCD-••••-...-3456"
|
||||
}
|
||||
```
|
||||
|
||||
### DecodeResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"payload_type": "text",
|
||||
"message": "string",
|
||||
"file_data_base64": null,
|
||||
"filename": null,
|
||||
"mime_type": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### HTTP Status Codes
|
||||
|
||||
| Code | Meaning | Use Case |
|
||||
|------|---------|----------|
|
||||
| 200 | OK | Successful operation |
|
||||
| 400 | Bad Request | Invalid input, capacity error, invalid channel key |
|
||||
| 401 | Unauthorized | Decryption failed, channel key mismatch |
|
||||
| 500 | Internal Error | Unexpected server error |
|
||||
| 501 | Not Implemented | Feature unavailable |
|
||||
|
||||
### Channel Key Errors
|
||||
|
||||
| Status | Error | Cause |
|
||||
|--------|-------|-------|
|
||||
| 400 | "Invalid channel key format" | Key doesn't match `XXXX-XXXX-...` pattern |
|
||||
| 401 | "Message encoded with channel key but none configured" | Need to provide channel key |
|
||||
| 401 | "Message encoded without channel key" | Use `channel_key=""` or `"none"` |
|
||||
|
||||
---
|
||||
|
||||
## Code Examples
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
BASE_URL = "http://localhost:8000"
|
||||
|
||||
# Check channel status
|
||||
status = requests.get(f"{BASE_URL}/channel/status").json()
|
||||
print(f"Channel mode: {status['mode']}")
|
||||
print(f"Fingerprint: {status.get('fingerprint', 'N/A')}")
|
||||
|
||||
# Generate channel key
|
||||
response = requests.post(f"{BASE_URL}/channel/generate?save=true")
|
||||
key_info = response.json()
|
||||
print(f"Generated: {key_info['fingerprint']}")
|
||||
|
||||
# Encode with channel key (auto from server)
|
||||
with open("ref.jpg", "rb") as ref, open("carrier.png", "rb") as carrier:
|
||||
response = requests.post(f"{BASE_URL}/encode/multipart", files={
|
||||
"reference_photo": ref,
|
||||
"carrier": carrier,
|
||||
}, data={
|
||||
"message": "Team secret",
|
||||
"passphrase": "apple forest thunder",
|
||||
"pin": "123456",
|
||||
# channel_key defaults to "auto" (use server config)
|
||||
})
|
||||
|
||||
with open("stego.png", "wb") as f:
|
||||
f.write(response.content)
|
||||
|
||||
print(f"Channel mode: {response.headers.get('X-Stegasoo-Channel-Mode')}")
|
||||
|
||||
# Encode with explicit channel key
|
||||
with open("ref.jpg", "rb") as ref, open("carrier.png", "rb") as carrier:
|
||||
response = requests.post(f"{BASE_URL}/encode/multipart", files={
|
||||
"reference_photo": ref,
|
||||
"carrier": carrier,
|
||||
}, data={
|
||||
"message": "Using explicit key",
|
||||
"passphrase": "words here",
|
||||
"pin": "123456",
|
||||
"channel_key": "ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456",
|
||||
})
|
||||
|
||||
# Decode
|
||||
with open("ref.jpg", "rb") as ref, open("stego.png", "rb") as stego:
|
||||
response = requests.post(f"{BASE_URL}/decode/multipart", files={
|
||||
"reference_photo": ref,
|
||||
"stego_image": stego,
|
||||
}, data={
|
||||
"passphrase": "apple forest thunder",
|
||||
"pin": "123456",
|
||||
# channel_key defaults to "auto"
|
||||
})
|
||||
|
||||
result = response.json()
|
||||
print(f"Decoded: {result.get('message')}")
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
const axios = require('axios');
|
||||
const FormData = require('form-data');
|
||||
const fs = require('fs');
|
||||
|
||||
const BASE_URL = 'http://localhost:8000';
|
||||
|
||||
async function main() {
|
||||
// Check channel status
|
||||
const status = await axios.get(`${BASE_URL}/channel/status`);
|
||||
console.log('Channel:', status.data.mode);
|
||||
|
||||
// Encode with auto channel key
|
||||
const form = new FormData();
|
||||
form.append('passphrase', 'apple forest thunder');
|
||||
form.append('pin', '123456');
|
||||
form.append('message', 'Secret');
|
||||
form.append('reference_photo', fs.createReadStream('ref.jpg'));
|
||||
form.append('carrier', fs.createReadStream('carrier.png'));
|
||||
// channel_key defaults to "auto" (use server config)
|
||||
|
||||
const response = await axios.post(`${BASE_URL}/encode/multipart`, form, {
|
||||
headers: form.getHeaders(),
|
||||
responseType: 'arraybuffer'
|
||||
});
|
||||
|
||||
fs.writeFileSync('stego.png', response.data);
|
||||
console.log('Channel mode:', response.headers['x-stegasoo-channel-mode']);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
### cURL / Bash
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
BASE_URL="http://localhost:8000"
|
||||
|
||||
# Check channel status
|
||||
echo "Channel status:"
|
||||
curl -s "$BASE_URL/channel/status" | jq .
|
||||
|
||||
# Generate and save channel key
|
||||
echo "Generating channel key..."
|
||||
curl -s -X POST "$BASE_URL/channel/generate?save=true" | jq .
|
||||
|
||||
# Encode (channel_key defaults to "auto")
|
||||
echo "Encoding..."
|
||||
curl -s -X POST "$BASE_URL/encode/multipart" \
|
||||
-F "passphrase=apple forest thunder" \
|
||||
-F "pin=123456" \
|
||||
-F "message=Secret message" \
|
||||
-F "reference_photo=@ref.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
|
||||
echo "Encoded to stego.png"
|
||||
|
||||
# Decode
|
||||
echo "Decoding..."
|
||||
curl -s -X POST "$BASE_URL/decode/multipart" \
|
||||
-F "passphrase=apple forest thunder" \
|
||||
-F "pin=123456" \
|
||||
-F "reference_photo=@ref.jpg" \
|
||||
-F "stego_image=@stego.png" | jq .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker Configuration
|
||||
|
||||
### docker-compose.yml
|
||||
|
||||
```yaml
|
||||
x-common-env: &common-env
|
||||
STEGASOO_CHANNEL_KEY: ${STEGASOO_CHANNEL_KEY:-}
|
||||
|
||||
services:
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
target: api
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
<<: *common-env
|
||||
```
|
||||
|
||||
### .env (gitignored)
|
||||
|
||||
```bash
|
||||
STEGASOO_CHANNEL_KEY=ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
```
|
||||
|
||||
### Generate key for .env
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://localhost:8000/channel/generate | \
|
||||
jq -r '"STEGASOO_CHANNEL_KEY=\(.key)"' >> .env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [CLI Documentation](CLI.md) - Command-line interface
|
||||
- [Web UI Documentation](WEB_UI.md) - Browser interface
|
||||
- [README](../README.md) - Project overview
|
||||
759
frontends/CLI.md
759
frontends/CLI.md
@@ -1,759 +0,0 @@
|
||||
# Stegasoo CLI Documentation (v4.0.1)
|
||||
|
||||
Complete command-line interface reference for Stegasoo steganography operations.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Installation](#installation)
|
||||
- [What's New in v4.0.0](#whats-new-in-v400)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Commands](#commands)
|
||||
- [generate](#generate-command)
|
||||
- [encode](#encode-command)
|
||||
- [decode](#decode-command)
|
||||
- [verify](#verify-command)
|
||||
- [channel](#channel-command)
|
||||
- [info](#info-command)
|
||||
- [compare](#compare-command)
|
||||
- [modes](#modes-command)
|
||||
- [strip-metadata](#strip-metadata-command)
|
||||
- [Channel Keys](#channel-keys)
|
||||
- [Embedding Modes](#embedding-modes)
|
||||
- [Security Factors](#security-factors)
|
||||
- [Workflow Examples](#workflow-examples)
|
||||
- [Piping & Scripting](#piping--scripting)
|
||||
- [Error Handling](#error-handling)
|
||||
- [Exit Codes](#exit-codes)
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### From PyPI
|
||||
|
||||
```bash
|
||||
# CLI only
|
||||
pip install stegasoo[cli]
|
||||
|
||||
# CLI with DCT support
|
||||
pip install stegasoo[cli,dct]
|
||||
|
||||
# With all extras
|
||||
pip install stegasoo[all]
|
||||
```
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/example/stegasoo.git
|
||||
cd stegasoo
|
||||
pip install -e ".[cli,dct]"
|
||||
```
|
||||
|
||||
### Verify Installation
|
||||
|
||||
```bash
|
||||
stegasoo --version
|
||||
stegasoo --help
|
||||
|
||||
# Check DCT support
|
||||
python -c "from stegasoo import has_dct_support; print('DCT:', 'available' if has_dct_support() else 'requires scipy')"
|
||||
|
||||
# Check channel key status
|
||||
stegasoo channel show
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What's New in v4.0.0
|
||||
|
||||
Version 4.0.0 adds **channel key** support for deployment/group isolation:
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| Channel keys | 256-bit keys that isolate message groups |
|
||||
| Deployment isolation | Different deployments can't read each other's messages |
|
||||
| CLI management | New `stegasoo channel` command group |
|
||||
| Flexible override | Use server config, explicit key, or public mode |
|
||||
|
||||
**Key benefits:**
|
||||
- ✅ Isolate messages between teams, deployments, or groups
|
||||
- ✅ Same credentials can't decode messages from different channels
|
||||
- ✅ Backward compatible (public mode = no channel key)
|
||||
- ✅ Easy key distribution via environment variables or config files
|
||||
|
||||
**Breaking change:** v4.0.0 messages (with channel key) cannot be decoded by v3.x installations.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Generate credentials (do this once, memorize results)
|
||||
stegasoo generate
|
||||
|
||||
# 2. (Optional) Set up channel key for deployment isolation
|
||||
stegasoo channel generate --save
|
||||
|
||||
# 3. Encode a message (uses configured channel key automatically)
|
||||
stegasoo encode \
|
||||
--ref secret_photo.jpg \
|
||||
--carrier meme.png \
|
||||
--passphrase "apple forest thunder mountain" \
|
||||
--pin 123456 \
|
||||
--message "Meet at midnight"
|
||||
|
||||
# 4. Decode a message (uses same channel key)
|
||||
stegasoo decode \
|
||||
--ref secret_photo.jpg \
|
||||
--stego stego_abc123.png \
|
||||
--passphrase "apple forest thunder mountain" \
|
||||
--pin 123456
|
||||
|
||||
# 5. Decode without channel key (public mode)
|
||||
stegasoo decode \
|
||||
--ref secret_photo.jpg \
|
||||
--stego public_stego.png \
|
||||
--passphrase "words here now" \
|
||||
--pin 123456 \
|
||||
--no-channel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
### Generate Command
|
||||
|
||||
Generate credentials for encoding/decoding operations.
|
||||
|
||||
#### Synopsis
|
||||
|
||||
```bash
|
||||
stegasoo generate [OPTIONS]
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
| Option | Short | Type | Default | Description |
|
||||
|--------|-------|------|---------|-------------|
|
||||
| `--pin/--no-pin` | | flag | `--pin` | Generate a PIN |
|
||||
| `--rsa/--no-rsa` | | flag | `--no-rsa` | Generate an RSA key |
|
||||
| `--pin-length` | | 6-9 | 6 | PIN length in digits |
|
||||
| `--rsa-bits` | | choice | 2048 | RSA key size (2048, 3072, 4096) |
|
||||
| `--words` | | 3-12 | 4 | Words in passphrase |
|
||||
| `--output` | `-o` | path | | Save RSA key to file |
|
||||
| `--password` | `-p` | string | | Password for RSA key file |
|
||||
| `--json` | | flag | | Output as JSON |
|
||||
|
||||
#### Examples
|
||||
|
||||
```bash
|
||||
# Basic generation with PIN (default)
|
||||
stegasoo generate
|
||||
|
||||
# Generate with more words for higher security
|
||||
stegasoo generate --words 6
|
||||
|
||||
# Generate with RSA key
|
||||
stegasoo generate --rsa --rsa-bits 4096
|
||||
|
||||
# Save RSA key to encrypted file
|
||||
stegasoo generate --rsa -o mykey.pem -p "mysecretpassword"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Encode Command
|
||||
|
||||
Encode a secret message or file into an image.
|
||||
|
||||
#### Synopsis
|
||||
|
||||
```bash
|
||||
stegasoo encode [OPTIONS]
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
| Option | Short | Type | Required | Default | Description |
|
||||
|--------|-------|------|----------|---------|-------------|
|
||||
| `--ref` | `-r` | path | ✓ | | Reference photo |
|
||||
| `--carrier` | `-c` | path | ✓ | | Carrier image |
|
||||
| `--passphrase` | `-p` | string | ✓ | | Passphrase |
|
||||
| `--message` | `-m` | string | | | Message to encode |
|
||||
| `--message-file` | `-f` | path | | | Read message from file |
|
||||
| `--embed-file` | `-e` | path | | | Embed a binary file |
|
||||
| `--pin` | | string | * | | Static PIN (6-9 digits) |
|
||||
| `--key` | `-k` | path | * | | RSA key file |
|
||||
| `--key-qr` | | path | * | | RSA key from QR code |
|
||||
| `--key-password` | | string | | | RSA key password |
|
||||
| `--channel` | | string | | auto | Channel key (v4.0.0) |
|
||||
| `--channel-file` | | path | | | Read channel key from file |
|
||||
| `--no-channel` | | flag | | | Force public mode |
|
||||
| `--output` | `-o` | path | | | Output filename |
|
||||
| `--mode` | | choice | | `lsb` | Embedding mode |
|
||||
| `--dct-format` | | choice | | `png` | DCT output format |
|
||||
| `--dct-color` | | choice | | `grayscale` | DCT color mode |
|
||||
| `--quiet` | `-q` | flag | | | Suppress output |
|
||||
|
||||
\* At least one of `--pin`, `--key`, or `--key-qr` is required.
|
||||
|
||||
#### Channel Key Options
|
||||
|
||||
| Option | Effect |
|
||||
|--------|--------|
|
||||
| *(none)* | Use server-configured key (auto mode) |
|
||||
| `--channel KEY` | Use explicit channel key |
|
||||
| `--channel auto` | Same as no option |
|
||||
| `--channel-file F` | Read channel key from file |
|
||||
| `--no-channel` | Force public mode (no isolation) |
|
||||
|
||||
#### Examples
|
||||
|
||||
```bash
|
||||
# Basic encoding (uses server channel key if configured)
|
||||
stegasoo encode \
|
||||
-r photo.jpg -c meme.png \
|
||||
-p "correct horse battery staple" \
|
||||
--pin 847293 \
|
||||
-m "The package arrives Tuesday"
|
||||
|
||||
# With explicit channel key
|
||||
stegasoo encode \
|
||||
-r photo.jpg -c meme.png \
|
||||
-p "correct horse battery staple" \
|
||||
--pin 847293 \
|
||||
-m "Secret message" \
|
||||
--channel ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
|
||||
# Public mode (no channel isolation)
|
||||
stegasoo encode \
|
||||
-r photo.jpg -c meme.png \
|
||||
-p "correct horse battery staple" \
|
||||
--pin 847293 \
|
||||
-m "Public message" \
|
||||
--no-channel
|
||||
|
||||
# DCT mode for social media
|
||||
stegasoo encode \
|
||||
-r photo.jpg -c meme.png \
|
||||
-p "words here" --pin 847293 \
|
||||
-m "Secret" \
|
||||
--mode dct --dct-format jpeg
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Decode Command
|
||||
|
||||
Decode a secret message or file from a stego image.
|
||||
|
||||
#### Synopsis
|
||||
|
||||
```bash
|
||||
stegasoo decode [OPTIONS]
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
| Option | Short | Type | Required | Default | Description |
|
||||
|--------|-------|------|----------|---------|-------------|
|
||||
| `--ref` | `-r` | path | ✓ | | Reference photo |
|
||||
| `--stego` | `-s` | path | ✓ | | Stego image |
|
||||
| `--passphrase` | `-p` | string | ✓ | | Passphrase |
|
||||
| `--pin` | | string | * | | Static PIN |
|
||||
| `--key` | `-k` | path | * | | RSA key file |
|
||||
| `--key-qr` | | path | * | | RSA key from QR code |
|
||||
| `--key-password` | | string | | | RSA key password |
|
||||
| `--channel` | | string | | auto | Channel key (v4.0.0) |
|
||||
| `--channel-file` | | path | | | Read channel key from file |
|
||||
| `--no-channel` | | flag | | | Force public mode |
|
||||
| `--output` | `-o` | path | | | Save output to file |
|
||||
| `--mode` | | choice | | `auto` | Extraction mode |
|
||||
| `--quiet` | `-q` | flag | | | Minimal output |
|
||||
| `--force` | | flag | | | Overwrite existing file |
|
||||
|
||||
#### Examples
|
||||
|
||||
```bash
|
||||
# Basic decoding (uses server channel key)
|
||||
stegasoo decode \
|
||||
-r photo.jpg -s stego.png \
|
||||
-p "correct horse battery staple" \
|
||||
--pin 847293
|
||||
|
||||
# With explicit channel key
|
||||
stegasoo decode \
|
||||
-r photo.jpg -s stego.png \
|
||||
-p "words here" --pin 847293 \
|
||||
--channel ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
|
||||
# Decode public image (no channel key was used)
|
||||
stegasoo decode \
|
||||
-r photo.jpg -s stego.png \
|
||||
-p "words here" --pin 847293 \
|
||||
--no-channel
|
||||
|
||||
# Save to file
|
||||
stegasoo decode \
|
||||
-r photo.jpg -s stego.png \
|
||||
-p "words" --pin 123456 \
|
||||
-o decoded.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Verify Command
|
||||
|
||||
Verify credentials without extracting the message.
|
||||
|
||||
#### Synopsis
|
||||
|
||||
```bash
|
||||
stegasoo verify [OPTIONS]
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
Same as `decode`, minus `--output` and `--force`. Adds `--json` for JSON output.
|
||||
|
||||
#### Examples
|
||||
|
||||
```bash
|
||||
# Quick verification
|
||||
stegasoo verify -r photo.jpg -s stego.png -p "phrase" --pin 123456
|
||||
|
||||
# With explicit channel key
|
||||
stegasoo verify -r photo.jpg -s stego.png -p "phrase" --pin 123456 \
|
||||
--channel ABCD-1234-...
|
||||
|
||||
# JSON output
|
||||
stegasoo verify -r photo.jpg -s stego.png -p "phrase" --pin 123456 --json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Channel Command
|
||||
|
||||
Manage channel keys for deployment/group isolation.
|
||||
|
||||
#### Subcommands
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `generate` | Create a new channel key |
|
||||
| `show` | Display current channel key status |
|
||||
| `set` | Save a channel key to config |
|
||||
| `clear` | Remove channel key from config |
|
||||
|
||||
#### channel generate
|
||||
|
||||
```bash
|
||||
stegasoo channel generate [OPTIONS]
|
||||
```
|
||||
|
||||
| Option | Short | Description |
|
||||
|--------|-------|-------------|
|
||||
| `--save` | `-s` | Save to user config (~/.stegasoo/channel.key) |
|
||||
| `--save-project` | | Save to project config (./config/channel.key) |
|
||||
| `--env` | `-e` | Output as environment variable export |
|
||||
| `--quiet` | `-q` | Output only the key |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Just display a new key
|
||||
stegasoo channel generate
|
||||
|
||||
# Save to user config
|
||||
stegasoo channel generate --save
|
||||
|
||||
# Add to .env file
|
||||
stegasoo channel generate --env >> .env
|
||||
|
||||
# For scripts
|
||||
KEY=$(stegasoo channel generate -q)
|
||||
```
|
||||
|
||||
#### channel show
|
||||
|
||||
```bash
|
||||
stegasoo channel show [OPTIONS]
|
||||
```
|
||||
|
||||
| Option | Short | Description |
|
||||
|--------|-------|-------------|
|
||||
| `--reveal` | `-r` | Show full key (not just fingerprint) |
|
||||
| `--json` | | Output as JSON |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Show status (fingerprint only)
|
||||
stegasoo channel show
|
||||
|
||||
# Reveal full key
|
||||
stegasoo channel show --reveal
|
||||
|
||||
# JSON for scripts
|
||||
stegasoo channel show --json
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```
|
||||
─── CHANNEL KEY STATUS ───
|
||||
|
||||
Mode: PRIVATE
|
||||
Fingerprint: ABCD-••••-••••-••••-••••-••••-••••-3456
|
||||
Source: ~/.stegasoo/channel.key
|
||||
|
||||
Messages require this channel key to decode.
|
||||
```
|
||||
|
||||
#### channel set
|
||||
|
||||
```bash
|
||||
stegasoo channel set [KEY] [OPTIONS]
|
||||
```
|
||||
|
||||
| Option | Short | Description |
|
||||
|--------|-------|-------------|
|
||||
| `--file` | `-f` | Read key from file |
|
||||
| `--project` | `-p` | Save to project config instead of user |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Set from command line
|
||||
stegasoo channel set ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
|
||||
# Set from file
|
||||
stegasoo channel set --file channel.key
|
||||
|
||||
# Set in project config
|
||||
stegasoo channel set XXXX-... --project
|
||||
```
|
||||
|
||||
#### channel clear
|
||||
|
||||
```bash
|
||||
stegasoo channel clear [OPTIONS]
|
||||
```
|
||||
|
||||
| Option | Short | Description |
|
||||
|--------|-------|-------------|
|
||||
| `--project` | `-p` | Clear project config |
|
||||
| `--all` | | Clear both user and project configs |
|
||||
| `--force` | `-f` | Skip confirmation |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Clear user config (with confirmation)
|
||||
stegasoo channel clear
|
||||
|
||||
# Clear project config
|
||||
stegasoo channel clear --project
|
||||
|
||||
# Clear all configs without confirmation
|
||||
stegasoo channel clear --all --force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Info Command
|
||||
|
||||
Show information about an image file.
|
||||
|
||||
```bash
|
||||
stegasoo info IMAGE [OPTIONS]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Compare Command
|
||||
|
||||
Compare embedding mode capacities for an image.
|
||||
|
||||
```bash
|
||||
stegasoo compare IMAGE [OPTIONS]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Modes Command
|
||||
|
||||
Show available embedding modes and their status.
|
||||
|
||||
```bash
|
||||
stegasoo modes
|
||||
```
|
||||
|
||||
Now also displays channel key status.
|
||||
|
||||
---
|
||||
|
||||
### Strip-Metadata Command
|
||||
|
||||
Remove all metadata from an image.
|
||||
|
||||
```bash
|
||||
stegasoo strip-metadata IMAGE [OPTIONS]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Channel Keys
|
||||
|
||||
Channel keys provide **deployment/group isolation** - messages encoded with a channel key can only be decoded by systems with the same key.
|
||||
|
||||
### Key Format
|
||||
|
||||
```
|
||||
ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
└──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘
|
||||
8 groups of 4 alphanumeric characters (256 bits)
|
||||
```
|
||||
|
||||
### Storage Locations
|
||||
|
||||
Channel keys are checked in this order:
|
||||
|
||||
| Priority | Location | Best For |
|
||||
|----------|----------|----------|
|
||||
| 1 | `STEGASOO_CHANNEL_KEY` env var | Docker, CI/CD |
|
||||
| 2 | `./config/channel.key` | Project-specific |
|
||||
| 3 | `~/.stegasoo/channel.key` | User default |
|
||||
|
||||
### Modes
|
||||
|
||||
| Mode | Description | CLI Option |
|
||||
|------|-------------|------------|
|
||||
| **Auto** | Use server-configured key | *(default)* |
|
||||
| **Explicit** | Use specific key | `--channel KEY` |
|
||||
| **Public** | No channel isolation | `--no-channel` |
|
||||
|
||||
### Fingerprints
|
||||
|
||||
For security, full keys aren't displayed by default. Instead, a fingerprint is shown:
|
||||
|
||||
```
|
||||
Full key: ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
Fingerprint: ABCD-••••-••••-••••-••••-••••-••••-3456
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
**Team isolation:**
|
||||
```bash
|
||||
# Team A
|
||||
export STEGASOO_CHANNEL_KEY=AAAA-1111-...
|
||||
|
||||
# Team B
|
||||
export STEGASOO_CHANNEL_KEY=BBBB-2222-...
|
||||
|
||||
# Messages from Team A can only be decoded by Team A
|
||||
```
|
||||
|
||||
**Development vs Production:**
|
||||
```bash
|
||||
# Development
|
||||
./config/channel.key contains DEV-KEY-...
|
||||
|
||||
# Production
|
||||
STEGASOO_CHANNEL_KEY=PROD-KEY-... in Docker
|
||||
|
||||
# Dev messages can't be decoded in production
|
||||
```
|
||||
|
||||
**Public messages:**
|
||||
```bash
|
||||
# Anyone with credentials can decode
|
||||
stegasoo encode ... --no-channel
|
||||
stegasoo decode ... --no-channel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Embedding Modes
|
||||
|
||||
### LSB Mode (Default)
|
||||
|
||||
```bash
|
||||
stegasoo encode ... --mode lsb
|
||||
```
|
||||
|
||||
| Aspect | Details |
|
||||
|--------|---------|
|
||||
| **Capacity** | ~375 KB for 1920×1080 |
|
||||
| **Output** | PNG only |
|
||||
| **Best For** | Maximum capacity |
|
||||
|
||||
### DCT Mode
|
||||
|
||||
```bash
|
||||
stegasoo encode ... --mode dct --dct-format jpeg --dct-color color
|
||||
```
|
||||
|
||||
| Aspect | Details |
|
||||
|--------|---------|
|
||||
| **Capacity** | ~65 KB for 1920×1080 |
|
||||
| **Output** | PNG or JPEG |
|
||||
| **Best For** | Social media, stealth |
|
||||
|
||||
---
|
||||
|
||||
## Security Factors
|
||||
|
||||
| Factor | Description | Entropy |
|
||||
|--------|-------------|---------|
|
||||
| Reference Photo | Shared image | ~80-256 bits |
|
||||
| Passphrase | BIP-39 words | ~44 bits (4 words) |
|
||||
| Static PIN | Numeric (6-9) | ~20 bits (6 digits) |
|
||||
| RSA Key | Shared key file | ~128 bits |
|
||||
| Channel Key (v4.0.0) | Deployment isolation | ~256 bits |
|
||||
|
||||
---
|
||||
|
||||
## Workflow Examples
|
||||
|
||||
### Team Setup with Channel Key
|
||||
|
||||
**Initial setup (team lead):**
|
||||
```bash
|
||||
# Generate team channel key
|
||||
stegasoo channel generate -q > team_channel.key
|
||||
|
||||
# Distribute to team members securely
|
||||
# (encrypted email, secure file share, etc.)
|
||||
```
|
||||
|
||||
**Team member setup:**
|
||||
```bash
|
||||
# Save received key
|
||||
stegasoo channel set --file team_channel.key
|
||||
|
||||
# Verify
|
||||
stegasoo channel show
|
||||
```
|
||||
|
||||
**Daily use:**
|
||||
```bash
|
||||
# Channel key is used automatically
|
||||
stegasoo encode -r ref.jpg -c meme.png -p "phrase" --pin 123456 -m "Team message"
|
||||
stegasoo decode -r ref.jpg -s stego.png -p "phrase" --pin 123456
|
||||
```
|
||||
|
||||
### Docker Deployment
|
||||
|
||||
**docker-compose.yml:**
|
||||
```yaml
|
||||
x-common-env: &common-env
|
||||
STEGASOO_CHANNEL_KEY: ${STEGASOO_CHANNEL_KEY:-}
|
||||
|
||||
services:
|
||||
web:
|
||||
environment:
|
||||
<<: *common-env
|
||||
api:
|
||||
environment:
|
||||
<<: *common-env
|
||||
```
|
||||
|
||||
**.env (gitignored):**
|
||||
```bash
|
||||
STEGASOO_CHANNEL_KEY=ABCD-1234-EFGH-5678-IJKL-9012-MNOP-3456
|
||||
```
|
||||
|
||||
### CI/CD Pipeline
|
||||
|
||||
```bash
|
||||
# Generate key for CI
|
||||
CHANNEL_KEY=$(stegasoo channel generate -q)
|
||||
|
||||
# Use in pipeline
|
||||
STEGASOO_CHANNEL_KEY=$CHANNEL_KEY stegasoo encode ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Piping & Scripting
|
||||
|
||||
### Extract channel key for scripts
|
||||
|
||||
```bash
|
||||
# Get just the key
|
||||
KEY=$(stegasoo channel show --json | jq -r '.key // empty')
|
||||
|
||||
# Get fingerprint
|
||||
FINGERPRINT=$(stegasoo channel show --json | jq -r '.fingerprint // "none"')
|
||||
|
||||
# Check if configured
|
||||
if stegasoo channel show --json | jq -e '.configured' > /dev/null; then
|
||||
echo "Channel key is configured"
|
||||
fi
|
||||
```
|
||||
|
||||
### Generate and use immediately
|
||||
|
||||
```bash
|
||||
# Generate, save, and use
|
||||
stegasoo channel generate --save
|
||||
stegasoo encode -r ref.jpg -c carrier.png -p "phrase" --pin 123456 -m "message"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Channel Key Errors
|
||||
|
||||
| Error | Cause | Solution |
|
||||
|-------|-------|----------|
|
||||
| "Invalid channel key format" | Key doesn't match pattern | Use `stegasoo channel generate` |
|
||||
| "Message encoded with channel key but none configured" | Missing channel key | Set key or use `--channel` |
|
||||
| "Message encoded without channel key" | Used `--no-channel` to encode | Decode with `--no-channel` |
|
||||
| "Channel key mismatch" | Wrong key | Verify correct key |
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
```bash
|
||||
# Check current channel status
|
||||
stegasoo channel show
|
||||
|
||||
# Try decoding with explicit key
|
||||
stegasoo decode ... --channel XXXX-XXXX-...
|
||||
|
||||
# Try decoding without channel key
|
||||
stegasoo decode ... --no-channel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| 0 | Success |
|
||||
| 1 | General error / decryption failed |
|
||||
| 2 | Invalid arguments/options |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `STEGASOO_CHANNEL_KEY` | Channel key for deployment isolation (v4.0.0) |
|
||||
| `PYTHONPATH` | Include `src/` for development |
|
||||
| `STEGASOO_DEBUG` | Enable debug output (set to `1`) |
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [API Documentation](API.md) - Python API reference
|
||||
- [Web UI Documentation](WEB_UI.md) - Browser interface guide
|
||||
- [README](../README.md) - Project overview and security model
|
||||
@@ -1,990 +0,0 @@
|
||||
# Stegasoo Web UI Documentation (v4.0.1)
|
||||
|
||||
Complete guide for the Stegasoo web-based steganography interface.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [What's New in v4.0.1](#whats-new-in-v401)
|
||||
- [Installation & Setup](#installation--setup)
|
||||
- [Pages & Features](#pages--features)
|
||||
- [Home Page](#home-page)
|
||||
- [Generate Credentials](#generate-credentials)
|
||||
- [Encode Message](#encode-message)
|
||||
- [Decode Message](#decode-message)
|
||||
- [About Page](#about-page)
|
||||
- [Embedding Modes](#embedding-modes)
|
||||
- [DCT Mode (Default)](#dct-mode-default)
|
||||
- [LSB Mode](#lsb-mode)
|
||||
- [User Interface Guide](#user-interface-guide)
|
||||
- [Workflow Examples](#workflow-examples)
|
||||
- [Security Features](#security-features)
|
||||
- [Configuration](#configuration)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Mobile Support](#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
|
||||
|
||||
```bash
|
||||
pip install stegasoo[web]
|
||||
```
|
||||
|
||||
This automatically installs DCT dependencies (scipy) for full functionality.
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/example/stegasoo.git
|
||||
cd stegasoo
|
||||
pip install -e ".[web]"
|
||||
```
|
||||
|
||||
### Running the Server
|
||||
|
||||
**Development:**
|
||||
```bash
|
||||
cd frontends/web
|
||||
python app.py
|
||||
```
|
||||
Server starts at http://localhost:5000
|
||||
|
||||
**Production with Gunicorn:**
|
||||
```bash
|
||||
cd frontends/web
|
||||
gunicorn --bind 0.0.0.0:5000 --workers 2 --threads 4 --timeout 60 app:app
|
||||
```
|
||||
|
||||
**Docker:**
|
||||
```bash
|
||||
docker-compose up web
|
||||
```
|
||||
|
||||
### First-Time Setup
|
||||
|
||||
1. Navigate to http://localhost:5000
|
||||
2. Click "Generate" to create your credentials
|
||||
3. **Memorize** your passphrase and PIN
|
||||
4. 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:
|
||||
1. **Reference Photo** - Shared secret image
|
||||
2. **Passphrase** - Your secret phrase (v3.2.0: same every time!)
|
||||
3. **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
|
||||
|
||||
1. Click "Download as .pem"
|
||||
2. Enter a password (minimum 8 characters)
|
||||
3. Click "Download Protected Key"
|
||||
4. Save the file securely
|
||||
5. Share with your communication partner through a secure channel
|
||||
|
||||
#### RSA Key QR Code
|
||||
|
||||
For easier sharing, you can also:
|
||||
1. Click "Download QR Code"
|
||||
2. Save the QR code image
|
||||
3. 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:
|
||||
|
||||
1. **Load Images** - Reference photo and carrier image
|
||||
2. **View Capacity** - Shows available capacity for DCT and LSB modes
|
||||
3. **Select Mode** - DCT (default) or LSB with inline tooltips
|
||||
4. **Enter Payload** - Text message or file
|
||||
5. **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
|
||||
|
||||
1. Upload reference photo and carrier image
|
||||
2. View capacity info panel
|
||||
3. Select embedding mode (DCT default)
|
||||
4. Choose payload type and enter content
|
||||
5. Enter passphrase and security factors
|
||||
6. Click "Encode Message"
|
||||
7. Wait for processing (shows spinner)
|
||||
8. 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:**
|
||||
|
||||
1. **Native Share** (mobile/supported browsers):
|
||||
- Uses Web Share API
|
||||
- Opens system share sheet
|
||||
- Can share directly to apps
|
||||
|
||||
2. **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)
|
||||
|
||||
1. Upload the same reference photo
|
||||
2. Upload the received stego image
|
||||
3. Enter your passphrase (no date needed!)
|
||||
4. Enter your PIN and/or RSA key
|
||||
5. Click "Decode Message"
|
||||
6. 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:
|
||||
1. **Check passphrase** - Must be exact match (case-sensitive)
|
||||
2. **Same reference photo** - Must be identical file
|
||||
3. **Correct PIN/RSA** - Match what was used for encoding
|
||||
4. **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:**
|
||||
1. Go to `/generate`
|
||||
2. Configure: PIN ✓, 4 words, 6 digits
|
||||
3. Click "Generate Credentials"
|
||||
4. **Write down** passphrase and PIN on paper
|
||||
5. **Memorize** over the next few days
|
||||
6. 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)
|
||||
|
||||
1. Go to `/encode`
|
||||
2. Upload your shared reference photo
|
||||
3. Upload any carrier image (meme, vacation photo, etc.)
|
||||
4. Type your secret message
|
||||
5. Enter your passphrase
|
||||
6. Enter your PIN
|
||||
7. Click "Encode Message"
|
||||
8. Download or share the resulting image
|
||||
9. Send via any channel (email, file transfer)
|
||||
|
||||
### Sending with DCT Mode
|
||||
|
||||
1. Go to `/encode`
|
||||
2. Upload your shared reference photo
|
||||
3. Upload carrier image
|
||||
4. Type your secret message
|
||||
5. Enter your passphrase and PIN
|
||||
6. **Expand "Advanced Options"**
|
||||
7. **Select "DCT" embedding mode**
|
||||
8. **Select "JPEG" output format** (optional)
|
||||
9. Click "Encode Message"
|
||||
10. Download and share
|
||||
|
||||
### Receiving a Secret Message (v3.2.0 Simplified)
|
||||
|
||||
1. Receive the stego image through any channel
|
||||
2. Go to `/decode`
|
||||
3. Upload the same reference photo
|
||||
4. Upload the received stego image
|
||||
5. Enter your passphrase (no date needed!)
|
||||
6. Enter your PIN
|
||||
7. Click "Decode Message"
|
||||
8. Read the secret message or download the file
|
||||
|
||||
### Embedding a File
|
||||
|
||||
1. Go to `/encode`
|
||||
2. Upload reference photo and carrier image
|
||||
3. Select "File" as payload type
|
||||
4. Upload the file to embed (max 2MB)
|
||||
5. Enter passphrase and PIN
|
||||
6. Click "Encode Message"
|
||||
7. Download the stego image
|
||||
|
||||
### Extracting a File
|
||||
|
||||
1. Go to `/decode`
|
||||
2. Upload reference photo and stego image
|
||||
3. Enter passphrase and PIN
|
||||
4. Click "Decode Message"
|
||||
5. Click "Download File" to save the extracted file
|
||||
|
||||
### Changing Credentials
|
||||
|
||||
To rotate to new credentials:
|
||||
1. Both parties generate new credentials together
|
||||
2. Agree on a cutover date
|
||||
3. Messages encoded before cutover use old credentials
|
||||
4. 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:**
|
||||
```bash
|
||||
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):**
|
||||
```nginx
|
||||
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:**
|
||||
```yaml
|
||||
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:**
|
||||
1. Verify exact passphrase (case-sensitive)
|
||||
2. Verify you're using the original reference photo
|
||||
3. 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:**
|
||||
1. Verify credentials match
|
||||
2. Try obtaining original file
|
||||
3. If using DCT mode, some modification is expected to work
|
||||
|
||||
#### "Carrier image too small"
|
||||
|
||||
**Cause:** Message too large for carrier capacity
|
||||
|
||||
**Solutions:**
|
||||
1. Use a larger carrier image (more pixels)
|
||||
2. Shorten the message
|
||||
3. Use LSB mode for more capacity
|
||||
|
||||
#### "Passphrase should have at least 4 words"
|
||||
|
||||
**Cause:** Passphrase too short (v3.2.0 warning)
|
||||
|
||||
**Solutions:**
|
||||
1. Use a longer passphrase for better security
|
||||
2. 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:**
|
||||
1. Reduce file size
|
||||
2. Use PNG, JPG, or BMP formats
|
||||
3. Try a different browser
|
||||
|
||||
#### RSA key password error
|
||||
|
||||
**Causes:**
|
||||
- Wrong password
|
||||
- Unencrypted key with password provided
|
||||
- Corrupted key file
|
||||
|
||||
**Solutions:**
|
||||
1. Verify the correct password
|
||||
2. If key is unencrypted, leave password blank
|
||||
3. Re-download or regenerate the key
|
||||
|
||||
#### DCT mode shows "requires scipy"
|
||||
|
||||
**Cause:** scipy library not installed
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
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)
|
||||
- Email
|
||||
- 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](CLI.md) - Command-line interface
|
||||
- [API Documentation](API.md) - REST API reference
|
||||
- [Web Frontend Update Summary](web/WEB_FRONTEND_UPDATE_SUMMARY_V3.2.0.md) - Migration details
|
||||
- [README](../README.md) - Project overview
|
||||
Reference in New Issue
Block a user