steganography
Flutter plugin and CLI tool: encrypt UTF-8 text (AES-256-GCM or GOST Magma CTR) and hide it inside PNG/JPEG images using native steganography on Android and iOS, with a desktop terminal interface for development and offline use.
What it does
Text (UTF-8)
↓ encrypt (AES-256-GCM or GOST Magma CTR)
Encrypted payload
↓ pack (STG1 / STG2 / STG4 header)
Binary payload
↓ embed (LSB or JPEG-DCT)
Stego image (PNG or JPEG)
Decryption reverses the pipeline. The same 32-byte key and steganography method must be used for both embed and extract.
Features
- Four steganography methods
lsb— least significant bits in RGB channels (high capacity, PNG output)dct— JPEG luma DCT coefficients, 1 bit per 8×8 blocktelegramRobust2— robust DCT for lossy messengers (resize to 1280 px + JPEG Q80)dctResidualModulation— survives heavy social-network recompression
- Two ciphers: AES-256-GCM (default) and GOST R 34.12-2015 Magma (CTR)
- Carriers: PNG and JPEG
- Native JPEG layer: libjpeg-turbo coefficient-domain embedding (C++/Kotlin/Swift)
- CLI: terminal commands for embed/extract on macOS/Linux (LSB in pure Dart; DCT methods via FFI)
Installation
dependencies:
steganography: ^0.1.0
import 'package:steganography/steganography.dart';
Quick start (Flutter)
import 'dart:typed_data';
import 'package:steganography/steganography.dart';
final key = Uint8List.fromList(List.filled(32, 0x42)); // 256-bit key
final controller = SteganographyController(
key: key,
method: SteganographyMethod.lsb,
cipher: SteganographyCipher.aes256Gcm,
);
// Embed text into a carrier image
final stegoBytes = await controller.encrypt(
imageBytes: carrierPngOrJpeg,
text: 'Secret message',
);
// Extract (same key + method)
final text = await controller.decrypt(imageBytes: stegoBytes);
controller.dispose(); // zeroes the key in memory
Choosing a method
| Method | Capacity | Robustness | Output format | Best for |
|---|---|---|---|---|
lsb |
High | Low (lossless only) | PNG | Maximum payload size |
dct |
~1 bit / 8×8 block | Moderate | JPEG | Standard JPEG workflow |
telegramRobust2 |
Lower (Hamming + repetition) | High | JPEG | Telegram-like messengers |
dctResidualModulation |
Lowest | Highest | JPEG | Aggressive recompression |
Choosing a cipher
| Cipher | Description |
|---|---|
aes256Gcm |
AES-256-GCM: 12-byte nonce + ciphertext + 16-byte MAC |
gostMagmaCtr |
GOST R 34.12-2015 «Магма» in CTR mode, 256-bit key |
Platform support
| Platform | Min version | Embed / extract |
|---|---|---|
| Android | API 21 | All four methods |
| iOS | 12.0 | All four methods |
| macOS / Linux (CLI) | — | lsb, dct, telegramRobust2 |
| Web / Windows / desktop Flutter | — | Not supported |
Example app
cd example
flutter pub get
flutter run
The example app lets you pick an image from the gallery, choose method and cipher, embed text, and extract it back.
Command-line tool
Run embed/extract from the terminal without the Flutter app. Useful for scripting, testing, and decrypting stego images on a desktop.
CLI method support
| Method | Engine | Input | Output | Native build |
|---|---|---|---|---|
lsb |
Pure Dart | PNG | PNG | Not required |
dct |
FFI (C++) | PNG / JPEG | JPEG | Required |
telegramRobust2 |
FFI (C++) | PNG / JPEG / etc. | JPEG | Required |
dctResidualModulation |
— | — | — | Not available in CLI yet |
Stego files produced by the CLI are compatible with the mobile plugin (and vice versa) when the same key, method, and cipher are used.
Setup
cd steganography
dart pub get
# One-time: build native library for DCT methods (macOS / Linux)
bash tool/build_native.sh
# → native/build/libjpegstego.dylib (or .so on Linux)
Commands
# Encrypt / embed (aliases: encrypt, embed)
dart run steganography encrypt \
-i cover.png \
-o stego.png \
-k <key> \
-m "secret message"
# LSB — no native build needed
dart run steganography encrypt -i cover.png -o stego.png -k <key> -m "hello"
# DCT — needs a large enough image (~1024×1024 for short messages)
dart run steganography encrypt -i photo.jpg -o stego.jpg -k <key> -m "hello" --method dct
# TelegramRobust2
dart run steganography encrypt -i cover.png -o stego.jpg -k <key> -m "hi" --method telegramRobust2
# Decrypt / extract (aliases: decrypt, extract)
dart run steganography decrypt -i stego.jpg -k <key> --method dct
# Read message from a file
dart run steganography encrypt -i cover.png -o stego.png -k <key> -m @message.txt
# GOST Magma instead of AES
dart run steganography encrypt -i cover.png -o stego.png -k <key> -m "secret" --cipher gost
Key format (-k)
| Format | Example |
|---|---|
| 64 hex digits (32 bytes) | deadbeef… (64 characters) |
| Path to a 32-byte key file | -k ./my.key |
| UTF-8 string, exactly 32 chars | -k 12345678901234567890123456789012 |
CLI options
| Flag | Commands | Description |
|---|---|---|
-i, --input |
all | Path to input image |
-o, --output |
encrypt | Path to output stego image |
-k, --key |
all | Encryption key (see formats above) |
-m, --message |
encrypt | Text to hide (@file to read from file) |
--method |
all | lsb (default), dct, telegramRobust2 |
--cipher |
encrypt | aes (default) or gost |
Environment variables
# Custom path to the native shared library
export STEGANOGRAPHY_NATIVE_LIB=/path/to/libjpegstego.dylib
CLI limitations
- DCT capacity: 1 bit per 8×8 JPEG block — use a large carrier (e.g. 1024×1024) for messages longer than a few bytes.
- TelegramRobust2 extract re-encodes the image to JPEG Q80 (same as on mobile). Cross-platform JPEG encoders may differ slightly.
- Native build is tested on macOS and Linux; Windows may work via CMake but is not verified.
Development
flutter pub get
flutter analyze
flutter test
Integration tests (device / emulator):
cd example
flutter test integration_test/plugin_integration_test.dart
Rebuild the desktop native library after C++ changes:
bash tool/build_native.sh
Project structure
lib/
steganography.dart # Public API
public/ # SteganographyController, enums
internal/ # Crypto, payload format, method channel
cli/ # Terminal tool (LSB + FFI JPEG)
bin/steganography.dart # CLI entry point
android/src/main/cpp/ # Native JPEG stego (CMake + JNI)
ios/jpeg_stego/ # Same C++ sources for iOS
native/ # Desktop CMake build for CLI FFI
example/ # Demo Flutter app
License
MIT — see LICENSE.
Libraries
- cli/cli_engine
- cli/jpeg_preprocess
- cli/jpeg_steganography
- cli/jpeg_stego_native
- cli/key_parser
- cli/lsb_steganography
- internal/data/crypto/crypto_service
- internal/data/crypto/gost_magma
- internal/data/payload_format
- internal/data/platform/steganography_method_channel
- internal/domain/steganography_engine
- public/domain/controllers/steganography_controller
- public/model/image_format
- public/model/steganography_cipher
- public/model/steganography_method
- steganography
- Image steganography with AES-256-GCM and GOST Magma encryption.