Moved all docs to root.
This commit is contained in:
882
API.md
Normal file
882
API.md
Normal file
@@ -0,0 +1,882 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user