Cybersecurity-Projects/PROJECTS/beginner/steganography-multi-tool/DEMO.md

258 lines
9.0 KiB
Markdown

<!-- ©AngelaMos | 2026 -->
<!-- DEMO.md -->
# crypha demo
A hands-on tour of every carrier, end to end, with the real output crypha produces. Nothing here is faked; each block is a command you can run and the result it gives back.
Two things to know before you start:
- crypha writes the recovered payload to **stdout** and a one-line status to **stderr**. On a terminal they run together, because the payload has no trailing newline. Redirect with `-o out.bin`, or use `--json`, when you want them cleanly separated.
- A passphrase from any source (`-k`, `CRYPHA_PASSPHRASE`, or the interactive prompt) always encrypts. crypha never writes plaintext when you asked for a key.
## Sample covers
Any files work. To reproduce this page exactly, make a throwaway set with tools you probably already have:
```bash
convert -size 640x480 gradient:navy-white -depth 8 PNG24:cover.png # an 8-bit truecolor image
ffmpeg -f lavfi -i "sine=frequency=440:duration=2" \
-ac 1 -c:a pcm_s16le cover.wav # 2 seconds of mono audio
ffmpeg -i cover.wav cover.flac # the same audio, as FLAC
convert -size 612x792 xc:white cover.pdf # a one-page PDF
printf 'The quick brown fox jumps over the lazy dog.' > cover.txt
printf 'https://angelamos.com/crypha' > qr.txt # the QR's visible content
```
The image carrier wants an 8-bit truecolor PNG (or a 24-bit BMP); the `-depth 8 PNG24:` above forces that, since ImageMagick otherwise defaults to a 16-bit PNG, which crypha refuses.
## What can it hide, and where
```console
$ crypha formats
FORMAT COVER OUTPUT OPTIONS DESCRIPTION
audio 16-bit PCM WAV or FLAC WAV - LSB of 16-bit PCM samples
image PNG or 24-bit BMP PNG - LSB of RGB pixel data
pdf PDF PDF attachment | metadata | append embedded attachment, metadata, or append-after-EOF
qr UTF-8 text (the QR's visible content) PNG - Reed-Solomon-correctable error injection
text any UTF-8 text text - zero-width U+200B and U+2060 characters
```
`capacity` tells you how much a specific cover will hold, plaintext and encrypted:
```console
$ crypha capacity -i cover.png --format image
FORMAT ENVELOPE MAX PLAINTEXT MAX ENCRYPTED NOTE
image 115196 115182 115128
$ crypha capacity -i qr.txt --format qr
FORMAT ENVELOPE MAX PLAINTEXT MAX ENCRYPTED NOTE
qr 52 38 does not fit
```
Point `capacity` at a cover with no `--format` and it reports every carrier at once, flagging the ones the cover cannot serve:
```console
$ crypha capacity -i cover.png
FORMAT ENVELOPE MAX PLAINTEXT MAX ENCRYPTED NOTE
audio n/a n/a n/a cover must be a 16-bit PCM WAV or a FLAC file
image 115196 115182 115128
pdf n/a n/a n/a cover must be a PDF
qr 0 0 does not fit
text unbounded unbounded unbounded
```
## image: LSB of RGB pixels
```console
$ crypha hide --format image -i cover.png -o stego.png -m "The treasure is buried under the third oak past the old mill."
OUTPUT stego.png
FORMAT image
PAYLOAD 61 bytes
ENVELOPE 75 bytes
ENCRYPTED no
COMPRESSED no
```
`reveal` needs no `--format`; it detects the carrier itself:
```console
$ crypha reveal stego.png
The treasure is buried under the third oak past the old mill.
revealed 61 bytes via image -> (stdout)
```
`stego.png` is pixel-for-pixel indistinguishable to the eye. The 61-byte message became a 75-byte envelope (a plaintext payload adds 14 bytes of framing) and rode in the low bit of the RGB channels.
## text: zero-width characters
```console
$ crypha hide --format text -i cover.txt -o stego.txt -m "Zero-width characters are invisible to the eye."
OUTPUT stego.txt
FORMAT text
PAYLOAD 47 bytes
ENVELOPE 61 bytes
ENCRYPTED no
COMPRESSED no
```
The stego file reads identically to the cover, but the byte count gives it away: the cover was 44 bytes and `stego.txt` is far larger, because the envelope was appended as invisible U+200B and U+2060 runes.
```console
$ crypha reveal stego.txt
Zero-width characters are invisible to the eye.
revealed 47 bytes via text -> (stdout)
```
## audio: LSB of PCM samples
```console
$ crypha hide --format audio -i cover.wav -o stego.wav -m "Frequencies carry more than music."
OUTPUT stego.wav
FORMAT audio
PAYLOAD 34 bytes
ENVELOPE 48 bytes
ENCRYPTED no
COMPRESSED no
$ crypha reveal stego.wav
Frequencies carry more than music.
revealed 34 bytes via audio -> (stdout)
```
The tone sounds the same; the payload lives in the low bit of each 16-bit sample. Hand it a FLAC cover and crypha decodes it, embeds, and writes the result back as a standard WAV:
```console
$ crypha hide --format audio -i cover.flac -o from-flac.wav -m "Decoded from FLAC, embedded, written back as WAV."
OUTPUT from-flac.wav
FORMAT audio
PAYLOAD 49 bytes
ENVELOPE 63 bytes
ENCRYPTED no
COMPRESSED no
$ crypha reveal from-flac.wav
Decoded from FLAC, embedded, written back as WAV.
revealed 49 bytes via audio -> (stdout)
```
## qr: Reed-Solomon error injection
This is the showpiece. The payload is injected as errors into the QR's data codewords, inside the Reed-Solomon correction budget. An ordinary scanner reads the visible content and silently self-heals the injected errors away; crypha reads the errors back as the hidden bytes.
```console
$ crypha hide --format qr -i qr.txt -o stego-qr.png -m "meet me at the docks, midnight"
OUTPUT stego-qr.png
FORMAT qr
PAYLOAD 30 bytes
ENVELOPE 44 bytes
ENCRYPTED no
COMPRESSED no
```
Scan `stego-qr.png` with any phone and you get `https://angelamos.com/crypha`. Point crypha at it and you get the secret. Auto-detect has to be careful here, because a QR stego is a PNG: it must not be mistaken for an ordinary image carrier. It is not.
```console
$ crypha reveal stego-qr.png
meet me at the docks, midnight
revealed 30 bytes via qr -> (stdout)
```
The 30-byte message fit in the 38-byte plaintext budget of this cover. An encrypted envelope (68 bytes of overhead) would not, which is exactly what `capacity` warned above.
## pdf: attachment, metadata, or append
The default technique embeds the envelope as a lossless file attachment:
```console
$ crypha hide --format pdf -i cover.pdf -o stego.pdf -m "Attached, not appended. Look inside the file."
OUTPUT stego.pdf
FORMAT pdf
PAYLOAD 45 bytes
ENVELOPE 59 bytes
ENCRYPTED no
COMPRESSED no
$ crypha reveal stego.pdf
Attached, not appended. Look inside the file.
revealed 45 bytes via pdf -> (stdout)
```
`--technique append` writes the envelope after the `%%EOF` marker instead, where it survives naive copies:
```console
$ crypha hide --format pdf --technique append -i cover.pdf -o stego-append.pdf -m "This rides after the EOF marker."
OUTPUT stego-append.pdf
FORMAT pdf (append)
PAYLOAD 32 bytes
ENVELOPE 46 bytes
ENCRYPTED no
COMPRESSED no
```
`reveal` tries every technique, so you never have to remember which one you used.
## Encryption, end to end
Set a passphrase, ask to encrypt, and (optionally) compress. Here the passphrase comes from the environment so it never lands in your shell history:
```console
$ export CRYPHA_PASSPHRASE="correct horse battery staple"
$ crypha hide --format image -i cover.png -o enc.png -m "Only the passphrase opens this." --encrypt --compress
OUTPUT enc.png
FORMAT image
PAYLOAD 31 bytes
ENVELOPE 105 bytes
ENCRYPTED yes
COMPRESSED yes
```
With the right passphrase it comes straight back:
```console
$ crypha reveal enc.png
Only the passphrase opens this.
revealed 31 bytes via image -> (stdout)
```
With the wrong one, it fails closed. The header is authenticated, so a bad key or a tampered byte fails to open rather than returning garbage:
```console
$ CRYPHA_PASSPHRASE="wrong" crypha reveal enc.png
crypha: decryption failed (wrong passphrase or tampered data)
$ echo $?
1
```
## JSON for scripts
Every command takes a global `--json`. `reveal --json` base64-encodes the payload so binary is safe to pipe:
```console
$ crypha hide --format image -i cover.png -o j.png -m "json demo" --json
{
"format": "image",
"payload_bytes": 9,
"envelope_bytes": 23,
"encrypted": false,
"compressed": false,
"output": "j.png"
}
$ crypha reveal j.png --json
{
"format": "image",
"bytes": 9,
"encrypted": false,
"data": "anNvbiBkZW1v"
}
```
## The interactive wizard
Run `crypha` with no arguments in a terminal and it launches the bubbletea wizard: pick an operation, choose a format, browse to a cover with the file picker, type your message or select a payload file, set the secure options, and watch a live capacity meter fill as it checks the fit before embedding. It is the same engine as the CLI, so anything above works there too, with nothing to memorize.
```bash
crypha
```