Version 3.0.2 full expirimental DCT support, jpegio for better jpg manipulation, etc.
This commit is contained in:
449
frontends/API.md
449
frontends/API.md
@@ -16,6 +16,7 @@ Complete REST API reference for Stegasoo steganography operations.
|
||||
- [POST /decode](#post-decode-json)
|
||||
- [POST /decode/multipart](#post-decodemultipart)
|
||||
- [POST /image/info](#post-imageinfo)
|
||||
- [Embedding Modes](#embedding-modes)
|
||||
- [Data Models](#data-models)
|
||||
- [Error Handling](#error-handling)
|
||||
- [Code Examples](#code-examples)
|
||||
@@ -29,12 +30,19 @@ Complete REST API reference for Stegasoo steganography operations.
|
||||
The Stegasoo REST API provides programmatic access to all steganography operations:
|
||||
|
||||
- **Generate** credentials (phrases, PINs, RSA keys)
|
||||
- **Encode** messages into images
|
||||
- **Decode** messages from images
|
||||
- **Encode** messages into images (LSB or DCT mode)
|
||||
- **Decode** messages from images (auto-detects mode)
|
||||
- **Analyze** image capacity
|
||||
|
||||
The API supports both JSON (base64-encoded images) and multipart form data (direct file uploads).
|
||||
|
||||
### What's New in v3.0.2
|
||||
|
||||
- **DCT Steganography Mode** - JPEG-resilient embedding
|
||||
- **Output Format Selection** - PNG or JPEG output
|
||||
- **Color Mode Selection** - Color or grayscale processing
|
||||
- **jpegio Integration** - Proper JPEG coefficient manipulation
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
@@ -45,6 +53,8 @@ The API supports both JSON (base64-encoded images) and multipart form data (dire
|
||||
pip install stegasoo[api]
|
||||
```
|
||||
|
||||
This automatically installs DCT dependencies (scipy, jpegio) for full functionality.
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
@@ -107,8 +117,10 @@ Host: localhost:8000
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0.1",
|
||||
"version": "3.0.2",
|
||||
"has_argon2": true,
|
||||
"has_dct": true,
|
||||
"has_jpegio": true,
|
||||
"day_names": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
|
||||
}
|
||||
```
|
||||
@@ -119,6 +131,8 @@ Host: localhost:8000
|
||||
|-------|------|-------------|
|
||||
| `version` | string | Stegasoo library version |
|
||||
| `has_argon2` | boolean | Whether Argon2id is available |
|
||||
| `has_dct` | boolean | Whether DCT mode is available (scipy) |
|
||||
| `has_jpegio` | boolean | Whether native JPEG DCT is available |
|
||||
| `day_names` | array | Day names for phrase mapping |
|
||||
|
||||
#### cURL Example
|
||||
@@ -245,22 +259,28 @@ Content-Type: application/json
|
||||
| `rsa_password` | string | | | Password for RSA key |
|
||||
| `date_str` | string | | | Date override (YYYY-MM-DD) |
|
||||
| `embedding_mode` | string | | `"lsb"` | `"lsb"` or `"dct"` |
|
||||
\* At least one of `pin` or `rsa_key_base64` required.
|
||||
| `output_format` | string | | `"png"` | `"png"` or `"jpeg"` (DCT only) |
|
||||
| `color_mode` | string | | `"color"` | `"color"` or `"grayscale"` (DCT only) |
|
||||
|
||||
\* At least one of `pin` or `rsa_key_base64` required.
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"stego_image_base64": "iVBORw0KGgo...",
|
||||
"filename": "a1b2c3d4_20251227.png",
|
||||
"capacity_used_percent": 12.4,
|
||||
"date_used": "2025-12-27",
|
||||
"day_of_week": "Saturday"
|
||||
}
|
||||
```
|
||||
|
||||
#### Response Fields
|
||||
|
||||
"stego_image_base64": "iVBORw0KGgo...",
|
||||
"filename": "a1b2c3d4_20251227.png",
|
||||
"capacity_used_percent": 12.4,
|
||||
"date_used": "2025-12-27",
|
||||
"day_of_week": "Saturday",
|
||||
"embedding_mode": "lsb",
|
||||
"output_format": "png",
|
||||
"color_mode": null
|
||||
}
|
||||
```
|
||||
|
||||
#### Response Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `stego_image_base64` | string | Base64-encoded stego image |
|
||||
@@ -272,7 +292,10 @@ Content-Type: application/json
|
||||
| `output_format` | string | Output format: `"png"` or `"jpeg"` |
|
||||
| `color_mode` | string\|null | Color mode (DCT only): `"color"` or `"grayscale"` |
|
||||
|
||||
# Prepare base64-encoded images
|
||||
#### cURL Example (LSB Mode - Default)
|
||||
|
||||
```bash
|
||||
# Prepare base64-encoded images
|
||||
REF_B64=$(base64 -w0 reference.jpg)
|
||||
CARRIER_B64=$(base64 -w0 carrier.png)
|
||||
|
||||
@@ -280,13 +303,16 @@ Content-Type: application/json
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"message\": \"Secret message\",
|
||||
\"reference_photo_base64\": \"$REF_B64\",
|
||||
\"reference_photo_base64\": \"$REF_B64\",
|
||||
\"carrier_image_base64\": \"$CARRIER_B64\",
|
||||
\"day_phrase\": \"apple forest thunder\",
|
||||
\"pin\": \"123456\"
|
||||
}" | jq -r '.stego_image_base64' | base64 -d > stego.png
|
||||
```
|
||||
|
||||
#### cURL Example (DCT Mode with JPEG Output)
|
||||
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/encode \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
@@ -304,6 +330,23 @@ curl -X POST http://localhost:8000/encode \
|
||||
---
|
||||
|
||||
### POST /encode/multipart
|
||||
|
||||
Encode a message using direct file uploads. Returns the stego image directly.
|
||||
|
||||
#### Request
|
||||
|
||||
```http
|
||||
POST /encode/multipart HTTP/1.1
|
||||
Host: localhost:8000
|
||||
Content-Type: multipart/form-data; boundary=----FormBoundary
|
||||
|
||||
------FormBoundary
|
||||
Content-Disposition: form-data; name="message"
|
||||
|
||||
Secret message here
|
||||
------FormBoundary
|
||||
Content-Disposition: form-data; name="day_phrase"
|
||||
|
||||
apple forest thunder
|
||||
------FormBoundary
|
||||
Content-Disposition: form-data; name="pin"
|
||||
@@ -330,6 +373,18 @@ Content-Disposition: form-data; name="pin"
|
||||
Content-Disposition: form-data; name="carrier"; filename="carrier.png"
|
||||
Content-Type: image/png
|
||||
|
||||
<binary image data>
|
||||
------FormBoundary--
|
||||
```
|
||||
|
||||
#### Form Fields
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `message` | string | ✓ | | Message to encode |
|
||||
| `reference_photo` | file | ✓ | | Reference photo file |
|
||||
| `carrier` | file | ✓ | | Carrier image file |
|
||||
| `day_phrase` | string | ✓ | | Today's passphrase |
|
||||
| `pin` | string | * | | Static PIN |
|
||||
| `rsa_key` | file | * | | RSA key file (.pem) |
|
||||
| `rsa_password` | string | | | Password for RSA key |
|
||||
@@ -344,83 +399,72 @@ Content-Type: image/png
|
||||
|
||||
Returns the image directly with headers:
|
||||
|
||||
- `Content-Disposition: attachment; filename=<generated_filename>.png`
|
||||
- `X-Stegasoo-Date: 2025-12-27` (date used for encoding)
|
||||
- `X-Stegasoo-Day: Saturday` (day of week for passphrase rotation)
|
||||
- `X-Stegasoo-Capacity-Percent: 12.4` (capacity used)
|
||||
|
||||
#### cURL Examples
|
||||
|
||||
**With PIN:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: image/png
|
||||
Content-Disposition: attachment; filename="a1b2c3d4_20251227.png"
|
||||
X-Stegasoo-Date: 2025-12-27
|
||||
X-Stegasoo-Day: Saturday
|
||||
X-Stegasoo-Capacity-Used: 12.4
|
||||
X-Stegasoo-Embedding-Mode: lsb
|
||||
X-Stegasoo-Output-Format: png
|
||||
|
||||
<binary image data>
|
||||
```
|
||||
|
||||
#### Response Headers
|
||||
|
||||
| Header | Description |
|
||||
|--------|-------------|
|
||||
| `Content-Type` | `image/png` or `image/jpeg` |
|
||||
--output stego.png
|
||||
```
|
||||
|
||||
**With RSA key:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
| `Content-Disposition` | Suggested filename |
|
||||
| `X-Stegasoo-Date` | Encoding date |
|
||||
-F "day_phrase=apple forest thunder" \
|
||||
| `X-Stegasoo-Day` | Day of week |
|
||||
| `X-Stegasoo-Capacity-Used` | Capacity percentage |
|
||||
| `X-Stegasoo-Embedding-Mode` | `lsb` or `dct` |
|
||||
| `X-Stegasoo-Output-Format` | `png` or `jpeg` |
|
||||
| `X-Stegasoo-Color-Mode` | `color` or `grayscale` (DCT only) |
|
||||
|
||||
#### cURL Example (DCT + JPEG)
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "rsa_password=keypassword" \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
```
|
||||
|
||||
**With both PIN and RSA:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "message=Secret message for social media" \
|
||||
-F "day_phrase=apple forest thunder" \
|
||||
-F "pin=123456" \
|
||||
-F "pin=123456" \
|
||||
-F "rsa_key=@mykey.pem" \
|
||||
-F "rsa_password=keypassword" \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.png
|
||||
```
|
||||
|
||||
**With custom date:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/encode/multipart \
|
||||
-F "embedding_mode=dct" \
|
||||
-F "output_format=jpeg" \
|
||||
-F "color_mode=color" \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "carrier=@carrier.png" \
|
||||
--output stego.jpg
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /decode (JSON)
|
||||
|
||||
Decode a message using base64-encoded images. Auto-detects embedding mode.
|
||||
|
||||
#### Request
|
||||
-F "day_phrase=monday phrase here" \
|
||||
|
||||
```http
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
POST /decode HTTP/1.1
|
||||
Host: localhost:8000
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### Request Body
|
||||
|
||||
### POST /decode (JSON)
|
||||
|
||||
Decode a message using base64-encoded images.
|
||||
|
||||
#### Request
|
||||
|
||||
```http
|
||||
POST /decode HTTP/1.1
|
||||
Host: localhost:8000
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `stego_image_base64` | string | ✓ | Base64-encoded stego image |
|
||||
| `reference_photo_base64` | string | ✓ | Base64-encoded reference photo |
|
||||
| `day_phrase` | string | ✓ | Passphrase for encoding day |
|
||||
| `pin` | string | * | Static PIN |
|
||||
| `rsa_key_base64` | string | * | Base64-encoded RSA key |
|
||||
| `day_phrase` | string | ✓ | Passphrase for encoding day |
|
||||
| `rsa_password` | string | | Password for RSA key |
|
||||
|
||||
\* Must match security factors used during encoding.
|
||||
|
||||
@@ -450,20 +494,27 @@ Content-Type: application/json
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"stego_image_base64\": \"$STEGO_B64\",
|
||||
```
|
||||
\"reference_photo_base64\": \"$REF_B64\",
|
||||
\"day_phrase\": \"apple forest thunder\",
|
||||
\"pin\": \"123456\"
|
||||
}"
|
||||
```
|
||||
|
||||
Decode a message using direct file uploads.
|
||||
---
|
||||
|
||||
### POST /decode/multipart
|
||||
|
||||
Decode using direct file uploads. Auto-detects embedding mode.
|
||||
|
||||
#### Form Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `stego_image` | file | ✓ | Stego image file |
|
||||
| `reference_photo` | file | ✓ | Reference photo file |
|
||||
| `day_phrase` | string | ✓ | Passphrase for encoding day |
|
||||
| `pin` | string | * | Static PIN |
|
||||
| `rsa_key` | file | * | RSA key file (.pem) |
|
||||
Content-Type: multipart/form-data
|
||||
| `rsa_password` | string | | Password for RSA key |
|
||||
|
||||
#### Response
|
||||
@@ -481,15 +532,7 @@ curl -X POST http://localhost:8000/decode \
|
||||
curl -X POST http://localhost:8000/decode/multipart \
|
||||
-F "day_phrase=apple forest thunder" \
|
||||
-F "pin=123456" \
|
||||
"message": "Secret message here"
|
||||
}
|
||||
```
|
||||
|
||||
#### cURL Examples
|
||||
|
||||
**With PIN:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/decode/multipart \
|
||||
-F "reference_photo=@reference.jpg" \
|
||||
-F "stego_image=@stego.png"
|
||||
```
|
||||
|
||||
@@ -499,20 +542,20 @@ Content-Type: multipart/form-data
|
||||
|
||||
Get image information and capacity for both LSB and DCT modes.
|
||||
|
||||
-F "day_phrase=apple forest thunder" \
|
||||
#### Request (JSON)
|
||||
|
||||
```http
|
||||
POST /image/info HTTP/1.1
|
||||
Host: localhost:8000
|
||||
Content-Type: application/json
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
#### Request (Multipart)
|
||||
|
||||
```bash
|
||||
Get information about an image's capacity.
|
||||
curl -X POST http://localhost:8000/image/info \
|
||||
-F "image=@carrier.png"
|
||||
#### Request
|
||||
```
|
||||
|
||||
#### Response
|
||||
@@ -521,35 +564,30 @@ curl -X POST http://localhost:8000/decode/multipart \
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `image` | file | ✓ | Image file to analyze |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"width": 1920,
|
||||
"pixels": 2073600,
|
||||
"format": "PNG",
|
||||
"mode": "RGB",
|
||||
"capacity": {
|
||||
}
|
||||
"lsb": {
|
||||
"bytes": 776970,
|
||||
|
||||
"kb": 758
|
||||
},
|
||||
"dct": {
|
||||
"bytes": 64800,
|
||||
"kb": 63,
|
||||
| `width` | integer | Image width in pixels |
|
||||
"note": "Approximate - actual capacity depends on image content"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Response Fields
|
||||
| `capacity_bytes` | integer | Maximum message capacity (bytes) |
|
||||
|
||||
| Field | Type | Description |
|
||||
|
||||
#### cURL Example
|
||||
|
||||
|-------|------|-------------|
|
||||
| `width` | integer | Image width in pixels |
|
||||
| `height` | integer | Image height in pixels |
|
||||
| `pixels` | integer | Total pixel count |
|
||||
| `format` | string | Image format (PNG, JPEG, etc.) |
|
||||
| `mode` | string | Color mode (RGB, L, etc.) |
|
||||
| `capacity.lsb.bytes` | integer | LSB capacity in bytes |
|
||||
@@ -558,8 +596,19 @@ Content-Type: multipart/form-data
|
||||
| `capacity.dct.kb` | integer | Estimated DCT capacity in KB |
|
||||
| `capacity.dct.note` | string | Capacity estimation note |
|
||||
|
||||
|
||||
### GenerateRequest
|
||||
---
|
||||
|
||||
## Embedding Modes
|
||||
|
||||
### LSB Mode (Default)
|
||||
|
||||
**Least Significant Bit** embedding modifies pixel values directly.
|
||||
|
||||
| Aspect | Details |
|
||||
|--------|---------|
|
||||
| **Parameter** | `"embedding_mode": "lsb"` |
|
||||
| **Capacity** | ~3 bits/pixel (~770 KB for 1920×1080) |
|
||||
| **Output** | PNG only (lossless required) |
|
||||
| **Resilience** | ❌ Destroyed by JPEG compression |
|
||||
| **Best For** | Maximum capacity, controlled channels |
|
||||
|
||||
@@ -570,15 +619,58 @@ Content-Type: multipart/form-data
|
||||
| Aspect | Details |
|
||||
|--------|---------|
|
||||
| **Parameter** | `"embedding_mode": "dct"` |
|
||||
|
||||
### GenerateResponse
|
||||
| **Capacity** | ~0.25 bits/pixel (~65 KB for 1920×1080) |
|
||||
| **Output** | PNG or JPEG |
|
||||
| **Resilience** | ✅ Survives JPEG compression |
|
||||
| **Best For** | Social media, messaging apps |
|
||||
|
||||
> ⚠️ **Experimental**: DCT mode may have edge cases. Test with your workflow.
|
||||
|
||||
### DCT Options
|
||||
```json
|
||||
|
||||
| Option | Values | Default | Description |
|
||||
"phrases": {"Monday": "...", "Tuesday": "...", ...},
|
||||
"pin": "123456",
|
||||
"rsa_key_pem": "-----BEGIN PRIVATE KEY-----...",
|
||||
"entropy": {"phrase": 33, "pin": 19, "rsa": 0, "total": 52}
|
||||
|--------|--------|---------|-------------|
|
||||
| `output_format` | `"png"`, `"jpeg"` | `"png"` | Output image format |
|
||||
| `color_mode` | `"color"`, `"grayscale"` | `"color"` | Color processing mode |
|
||||
|
||||
### Capacity Comparison
|
||||
|
||||
| Mode | 1920×1080 Capacity |
|
||||
|------|-------------------|
|
||||
| LSB (PNG) | ~770 KB |
|
||||
| DCT (PNG) | ~65 KB |
|
||||
| DCT (JPEG) | ~30-50 KB |
|
||||
|
||||
---
|
||||
|
||||
## Data Models
|
||||
|
||||
### GenerateRequest
|
||||
|
||||
```json
|
||||
{
|
||||
"use_pin": true,
|
||||
"use_rsa": false,
|
||||
"pin_length": 6,
|
||||
"rsa_bits": 2048,
|
||||
"words_per_phrase": 3
|
||||
}
|
||||
```
|
||||
|
||||
### GenerateResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"phrases": {"Monday": "...", "Tuesday": "...", ...},
|
||||
"pin": "123456",
|
||||
"rsa_key_pem": "-----BEGIN PRIVATE KEY-----...",
|
||||
"entropy": {"phrase": 33, "pin": 19, "rsa": 0, "total": 52}
|
||||
}
|
||||
```
|
||||
|
||||
### EncodeRequest
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "string",
|
||||
"reference_photo_base64": "string",
|
||||
@@ -618,7 +710,10 @@ curl -X POST http://localhost:8000/image/info \
|
||||
"day_phrase": "string",
|
||||
"pin": "string",
|
||||
"rsa_key_base64": "string",
|
||||
"rsa_password": "string"
|
||||
"rsa_password": "string"
|
||||
}
|
||||
```
|
||||
|
||||
### DecodeResponse
|
||||
|
||||
```json
|
||||
@@ -630,7 +725,10 @@ curl -X POST http://localhost:8000/image/info \
|
||||
|
||||
### ImageInfoResponse
|
||||
|
||||
### ImageInfoResponse
|
||||
```json
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"pixels": 2073600,
|
||||
"format": "PNG",
|
||||
"mode": "RGB",
|
||||
@@ -651,7 +749,8 @@ curl -X POST http://localhost:8000/image/info \
|
||||
```
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### HTTP Status Codes
|
||||
|
||||
@@ -662,8 +761,12 @@ curl -X POST http://localhost:8000/image/info \
|
||||
| 401 | Unauthorized | Decryption failed (wrong credentials) |
|
||||
| 500 | Internal Error | Unexpected server error |
|
||||
|
||||
| 500 | Internal Error | Unexpected server error |
|
||||
|
||||
### Error Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Error message describing the problem"
|
||||
}
|
||||
```
|
||||
|
||||
### Common Errors
|
||||
@@ -705,8 +808,11 @@ curl -X POST http://localhost:8000/image/info \
|
||||
# Encode using multipart (LSB mode - default)
|
||||
with open("reference.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": "Secret message",
|
||||
with open("reference.jpg", "rb") as ref, open("carrier.png", "rb") as carrier:
|
||||
"day_phrase": "apple forest thunder",
|
||||
"pin": "123456"
|
||||
})
|
||||
|
||||
@@ -730,7 +836,7 @@ creds = response.json()
|
||||
with open("stego_social.jpg", "wb") as f:
|
||||
f.write(response.content)
|
||||
|
||||
```
|
||||
# Decode using multipart (auto-detects mode)
|
||||
with open("reference.jpg", "rb") as ref, open("stego.png", "rb") as stego:
|
||||
response = requests.post(f"{BASE_URL}/decode/multipart", files={
|
||||
"reference_photo": ref,
|
||||
@@ -744,7 +850,24 @@ with open("reference.jpg", "rb") as ref, open("carrier.png", "rb") as carrier:
|
||||
print(f"Decoded: {result['message']}")
|
||||
print(f"Mode detected: {result['embedding_mode_detected']}")
|
||||
```
|
||||
form.append('day_phrase', 'apple forest thunder');
|
||||
|
||||
### JavaScript/Node.js
|
||||
|
||||
```javascript
|
||||
const FormData = require('form-data');
|
||||
const fs = require('fs');
|
||||
const axios = require('axios');
|
||||
|
||||
const BASE_URL = 'http://localhost:8000';
|
||||
|
||||
async function encodeDCT() {
|
||||
const form = new FormData();
|
||||
form.append('message', 'Secret message for social media');
|
||||
form.append('day_phrase', 'apple forest thunder');
|
||||
form.append('pin', '123456');
|
||||
form.append('embedding_mode', 'dct');
|
||||
form.append('output_format', 'jpeg');
|
||||
form.append('color_mode', 'color');
|
||||
form.append('reference_photo', fs.createReadStream('reference.jpg'));
|
||||
form.append('carrier', fs.createReadStream('carrier.png'));
|
||||
|
||||
@@ -754,7 +877,9 @@ with open("reference.jpg", "rb") as ref, open("stego.png", "rb") as stego:
|
||||
});
|
||||
|
||||
fs.writeFileSync('stego.jpg', response.data);
|
||||
fs.writeFileSync('stego.png', response.data);
|
||||
console.log('Encoded with DCT mode');
|
||||
console.log('Embedding mode:', response.headers['x-stegasoo-embedding-mode']);
|
||||
}
|
||||
|
||||
async function decode() {
|
||||
const form = new FormData();
|
||||
@@ -766,11 +891,14 @@ const axios = require('axios');
|
||||
const response = await axios.post(`${BASE_URL}/decode/multipart`, form, {
|
||||
headers: form.getHeaders()
|
||||
});
|
||||
headers: form.getHeaders()
|
||||
|
||||
console.log('Decoded:', response.data.message);
|
||||
|
||||
console.log('Mode detected:', response.data.embedding_mode_detected);
|
||||
}
|
||||
|
||||
encodeDCT().then(decode);
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```go
|
||||
@@ -779,8 +907,9 @@ async function encode() {
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
@@ -788,16 +917,17 @@ async function decode() {
|
||||
func main() {
|
||||
// Encode with DCT mode
|
||||
body := &bytes.Buffer{}
|
||||
)
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
writer.WriteField("message", "Secret message")
|
||||
writer.WriteField("day_phrase", "apple forest thunder")
|
||||
writer.WriteField("pin", "123456")
|
||||
writer.WriteField("embedding_mode", "dct")
|
||||
writer.WriteField("output_format", "jpeg")
|
||||
writer.WriteField("color_mode", "color")
|
||||
|
||||
ref, _ := os.Open("reference.jpg")
|
||||
writer.WriteField("pin", "123456")
|
||||
refPart, _ := writer.CreateFormFile("reference_photo", "reference.jpg")
|
||||
io.Copy(refPart, ref)
|
||||
ref.Close()
|
||||
|
||||
@@ -816,13 +946,16 @@ import (
|
||||
|
||||
// Check embedding mode from header
|
||||
fmt.Println("Embedding mode:", resp.Header.Get("X-Stegasoo-Embedding-Mode"))
|
||||
|
||||
|
||||
stego, _ := os.Create("stego.jpg")
|
||||
io.Copy(stego, resp.Body)
|
||||
stego.Close()
|
||||
resp.Body.Close()
|
||||
|
||||
fmt.Println("Encoded successfully with DCT mode")
|
||||
}
|
||||
```
|
||||
|
||||
### Shell Script (Bash)
|
||||
|
||||
```bash
|
||||
@@ -842,12 +975,15 @@ func main() {
|
||||
-F "day_phrase=$PHRASE" \
|
||||
-F "pin=$PIN" \
|
||||
-F "reference_photo=@$REF_PHOTO" \
|
||||
-F "day_phrase=$PHRASE" \
|
||||
-F "carrier=@$CARRIER" \
|
||||
--output stego_lsb.png
|
||||
|
||||
echo "Encoded to stego_lsb.png"
|
||||
|
||||
# Encode with DCT for social media
|
||||
echo "Encoding with DCT mode..."
|
||||
curl -s -X POST "$BASE_URL/encode/multipart" \
|
||||
|
||||
-F "message=$MESSAGE" \
|
||||
-F "day_phrase=$PHRASE" \
|
||||
-F "pin=$PIN" \
|
||||
-F "embedding_mode=dct" \
|
||||
@@ -863,27 +999,43 @@ PHRASE="apple forest thunder"
|
||||
echo "Decoding..."
|
||||
RESULT=$(curl -s -X POST "$BASE_URL/decode/multipart" \
|
||||
-F "day_phrase=$PHRASE" \
|
||||
## Rate Limiting
|
||||
|
||||
-F "pin=$PIN" \
|
||||
-F "reference_photo=@$REF_PHOTO" \
|
||||
-F "stego_image=@stego_dct.jpg")
|
||||
|
||||
echo "Decoded message: $(echo $RESULT | jq -r '.message')"
|
||||
echo "Mode detected: $(echo $RESULT | jq -r '.embedding_mode_detected')"
|
||||
```
|
||||
|
||||
```nginx
|
||||
---
|
||||
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
limit_req zone=stegasoo burst=20 nodelay;
|
||||
The API does not implement rate limiting by default. For production:
|
||||
|
||||
1. **Reverse Proxy**: Use nginx or Caddy rate limiting
|
||||
2. **Application Level**: Add FastAPI middleware
|
||||
|
||||
Example nginx rate limiting:
|
||||
```nginx
|
||||
limit_req_zone $binary_remote_addr zone=stegasoo:10m rate=10r/s;
|
||||
|
||||
location /api/ {
|
||||
limit_req zone=stegasoo burst=20 nodelay;
|
||||
proxy_pass http://localhost:8000/;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
}
|
||||
## Security Considerations
|
||||
|
||||
### In Transit
|
||||
|
||||
|
||||
- Use HTTPS in production
|
||||
- Configure TLS at reverse proxy level
|
||||
|
||||
|
||||
### Memory Usage
|
||||
|
||||
- Argon2id requires 256MB RAM per operation
|
||||
- DCT mode adds ~100MB for scipy operations
|
||||
@@ -917,9 +1069,15 @@ location /api/ {
|
||||
|------|--------------|
|
||||
| LSB | Maximum capacity but fragile |
|
||||
| DCT | Lower capacity but survives recompression |
|
||||
|
||||
Both modes use identical encryption (AES-256-GCM with Argon2id).
|
||||
|
||||
---
|
||||
|
||||
## Interactive Documentation
|
||||
|
||||
When the API is running, visit:
|
||||
|
||||
- **Swagger UI**: http://localhost:8000/docs
|
||||
- **ReDoc**: http://localhost:8000/redoc
|
||||
|
||||
@@ -927,6 +1085,8 @@ The API validates:
|
||||
|
||||
## See Also
|
||||
|
||||
- [CLI Documentation](CLI.md) - Command-line interface
|
||||
- [Web UI Documentation](WEB_UI.md) - Browser interface
|
||||
- [README](README.md) - Project overview
|
||||
### Credential Handling
|
||||
|
||||
@@ -934,6 +1094,15 @@ The API validates:
|
||||
- No persistent storage of secrets
|
||||
- Memory cleared after operations
|
||||
|
||||
### Embedding Mode Security
|
||||
|
||||
| Mode | Consideration |
|
||||
|------|--------------|
|
||||
| LSB | Maximum capacity but fragile |
|
||||
| DCT | Lower capacity but survives recompression |
|
||||
|
||||
Both modes use identical encryption (AES-256-GCM with Argon2id).
|
||||
|
||||
---
|
||||
|
||||
## Interactive Documentation
|
||||
|
||||
Reference in New Issue
Block a user