A secure command-line LSB (Least Significant Bit) steganography tool for hiding encrypted messages in PNG images.
- Strong Encryption: All messages are encrypted using ChaCha20-Poly1305 AEAD before embedding
- Customizable Keys: Use any password of any length (SHA256-hashed to derive 32-byte keys). Keys can include emoji and international characters (e.g., "我的密钥🔐")
- Multi-Image Support: Automatically split large messages across multiple images
- Auto-Resize: Automatically resize images to accommodate message size
- RGBA Encoding: Utilizes all four color channels (including alpha) for maximum capacity
- Rust 1.70 or later
- Cargo
git clone https://github.com/handsomecheung/lowkey.git
cd lowkey
cargo build --releaseThe compiled binary will be available at target/release/lowkey.
bash ./script/build.shlowkey encode --image input.jpg --message message.txt --output output.pnglowkey decode --image output.png --output recovered.txtlowkey encode --image input.jpg --message secret.txt --output output.png --key "my-secret-password"lowkey decode --image output.png --output recovered.txt --key "my-secret-password"Note: The same key must be used for both encoding and decoding.
# Using image list
lowkey encode --image-list img1.jpg img2.png img3.jpg --message large.txt --output-dir ./encoded
# Using directory
lowkey encode --image-dir ./images --message secret.txt --output-dir ./encoded --key "password"# Images are automatically ordered using sequence metadata
lowkey decode --image-list encoded/img1.png encoded/img2.png encoded/img3.png --output recovered.txt
# Using directory
lowkey decode --image-dir ./encoded --output recovered.txt --key "password"Automatically resize images when the message is too large:
lowkey encode --image small.jpg --message big.txt --output output.png --auto-resizeFull Unicode support for encryption keys:
lowkey encode --image input.jpg --message msg.txt --output output.png --key "MyKey🔐"
lowkey decode --image output.png --output msg.txt --key "MyKey🔐"lowkey uses Least Significant Bit (LSB) steganography to hide data in images:
- Each pixel in a PNG image has 4 color channels: Red, Green, Blue, and Alpha (transparency)
- Each channel is stored as an 8-bit value (0-255)
- The tool modifies the least significant bit of each channel to store hidden data
- This creates imperceptible changes to the image while embedding information
Storage Capacity: (width × height × 4) / 8 bytes per image
Before embedding, all messages are encrypted using:
- Algorithm: ChaCha20-Poly1305 AEAD (Authenticated Encryption with Associated Data)
- Key Derivation: SHA256 hashing of user-provided password (any length → 32 bytes)
- Nonce: 12 bytes, randomly generated per encryption
- Authentication: 16-byte Poly1305 MAC tag for integrity verification
Each encoded message contains:
- Version byte (1 byte): Protocol version for future compatibility
- Length field (4 bytes): Size of encrypted data
- Encrypted payload:
[12-byte nonce][ciphertext][16-byte auth tag]
When using multiple images, lowkey adds custom PNG metadata (lKsq chunk) to track:
- Current image index
- Total image count
This allows automatic ordering during decoding, regardless of input file order.
lowkey requires PNG output because:
- Lossless compression: PNG preserves every bit exactly as written
- RGBA support: Full access to all four color channels including alpha
- JPEG is lossy: Would destroy LSB-encoded data during compression
- Metadata support: PNG allows custom chunks for sequence information
Input images can be any format (JPEG, PNG, BMP, etc.), but they are converted to PNG for output.
cargo testbash ./tests/integration_test.shbash ./script/test.sh- The security of your hidden message depends on the strength of your encryption key
- Use long, random passwords for maximum security
- The default key is publicly known - always use
--keyfor sensitive data - LSB steganography can be detected by statistical analysis if someone suspects hidden data
- This tool is designed for legitimate privacy uses, not for evading lawful surveillance
Apache-2.0 license
Contributions are welcome! Please feel free to submit a Pull Request.
Built with:
- image-rs - Image processing
- png - PNG encoding/decoding
- RustCrypto - ChaCha20-Poly1305 and SHA2 implementations
- clap - Command-line argument parsing
- bitvec - Bit manipulation and vector operations