3 releases
Uses new Rust 2024
| 0.2.2 | Feb 4, 2026 |
|---|---|
| 0.2.1 | Feb 4, 2026 |
| 0.2.0 | Feb 4, 2026 |
#365 in Audio
92KB
2K
SLoC
Zim Steganography Toolkit (zimhide)
A Rust CLI for embedding and extracting encrypted text and audio in WAV files. Part of the Zim tool family.
Installation
Build
# With Opus compression (default) - requires libopus
cargo build --release
# Without Opus (no system dependencies, but larger embedded audio)
cargo build --release --no-default-features
The binary will be at target/release/zimhide.
Opus Compression (Optional)
By default, embedded audio is compressed with Opus (~10x smaller). This requires libopus:
- macOS:
brew install opus - Ubuntu/Debian:
apt install libopus-dev - Fedora:
dnf install opus-devel
If libopus is not available, build with --no-default-features to embed raw WAV bytes instead.
Quick Start
# Embed a message
zimhide encode input.wav -o output.wav --message "Hello, world!"
# Extract the message
zimhide decode output.wav
Commands
encode / decode
Embed and extract text from WAV files.
# Basic text embedding
zimhide encode input.wav -o output.wav --message "secret message"
zimhide decode output.wav
# From a file
zimhide encode input.wav -o output.wav --message-file secret.txt
zimhide decode output.wav
# Symmetric encryption (passphrase)
zimhide encode input.wav -o output.wav --message "secret" --passphrase "puzzle"
zimhide decode output.wav --passphrase "puzzle"
# Asymmetric encryption (public key)
zimhide encode input.wav -o output.wav --message "secret" --encrypt-to alice.pub
zimhide decode output.wav --key alice.priv
# Multi-recipient encryption
zimhide encode input.wav -o output.wav --message "secret" \
--encrypt-to alice.pub --encrypt-to bob.pub
zimhide decode output.wav --key alice.priv # Either recipient can decrypt
zimhide decode output.wav --key bob.priv
# Signed message
zimhide encode input.wav -o output.wav --message "verified" --sign --key my.priv
zimhide decode output.wav --verify my.pub
# Metadata method (stores in RIFF chunk, not hidden but preserves audio)
zimhide encode input.wav -o output.wav --message "data" --method metadata
zimhide decode output.wav
# LSB options
zimhide encode input.wav -o output.wav --message "data" --bits 2 --channels left
zimhide decode output.wav
Audio Embedding
Embed audio files inside a carrier WAV. The embedded audio is compressed with Opus (~10x compression).
Requirements: Embedded audio must be 48kHz, 16-bit WAV (mono or stereo).
# Convert audio to required format
ffmpeg -i voice.mp3 -ar 48000 -sample_fmt s16 voice_48k.wav
# Embed audio in carrier WAV
zimhide encode carrier.wav -o output.wav --audio voice_48k.wav --method metadata
# Embed audio with encryption
zimhide encode carrier.wav -o output.wav --audio voice_48k.wav --passphrase "secret"
# Embed both text and audio
zimhide encode carrier.wav -o output.wav --message "Note" --audio voice_48k.wav
play
Extract and play embedded audio.
# Play embedded audio (requires system audio player)
zimhide play output.wav
# Extract to file instead
zimhide play output.wav --extract-to recovered.wav
# With decryption
zimhide play output.wav --passphrase "secret"
zimhide play output.wav --key my.priv
keygen
Generate a keypair for encryption and signing.
# Save to files
zimhide keygen --output mykey
# Creates: mykey.pub and mykey.priv
# Output to stdout
zimhide keygen
inspect
Show embedded content metadata without decrypting.
zimhide inspect output.wav
# Example output:
# Zimhide Embedded Data
# =================
#
# Method: LSB (Least Significant Bit)
# Content: text
# Payload size: 83 bytes (encrypted)
# Encryption: symmetric (passphrase)
# Signed: no
#
# Total embedded: 93 bytes
# Capacity used: 0.8%
# Available: 11018 bytes
Steganography Methods
LSB (Least Significant Bit)
Default method. Modifies the least significant bits of audio samples to embed data. With 1 bit per sample (default), the modification is inaudible (-96dB for 16-bit audio).
Options:
--bits 1-4- Bits per sample (higher = more capacity, more audible)--channels left|right|both- Which channels to use
Metadata
Stores data in a custom RIFF chunk (zimH). Does not modify audio samples at all, but the chunk is visible to tools like ffprobe. Useful when audio fidelity is critical.
Cryptography
- Symmetric: Argon2id key derivation + ChaCha20-Poly1305
- Asymmetric: X25519 key exchange + XChaCha20-Poly1305
- Signatures: Ed25519
Key files use a PEM-like format:
-----BEGIN ZIMHIDE PUBLIC KEY-----
<base64 encoded key>
-----END ZIMHIDE PUBLIC KEY-----
Embedded Data Format
[4 bytes] Magic: "ZIMH"
[1 byte] Flags (text, audio, signed, symmetric, asymmetric)
[1 byte] Method (0=LSB, 1=metadata, 2=spread)
[4 bytes] Payload length
[N bytes] Payload (encrypted if applicable)
[64 bytes] Signature (if signed)
Shell Completions
Generate shell completions for your shell:
# Bash
zimhide completions bash > ~/.local/share/bash-completion/completions/zimhide
# Zsh (add to fpath)
zimhide completions zsh > ~/.zfunc/_zimhide
# Fish
zimhide completions fish > ~/.config/fish/completions/zimhide.fish
# PowerShell
zimhide completions powershell >> $PROFILE
For zsh, ensure ~/.zfunc is in your fpath. Add to ~/.zshrc:
fpath=(~/.zfunc $fpath)
autoload -Uz compinit && compinit
License
MIT
Dependencies
~6–14MB
~295K SLoC