LSB steganography in five minutes
How to hide bytes inside an image without changing how it looks. The technique behind Stiger, explained from scratch.
Steganography is the older cousin of cryptography. Cryptography says “you can see this, but you can’t read it.” Steganography says “you can’t see this.” Both can be used at once — and that’s what Stiger does — but the hiding part is worth understanding on its own.
The simplest, most-cited technique is LSB substitution: hide bytes in the least significant bits of an image. Five-minute version follows.
A pixel is three numbers
A normal PNG pixel is three numbers — red, green, blue — each from 0 to
255. A pixel of value (220, 100, 50) is some shade of orange. Change
the blue from 50 to 51, and the pixel becomes (220, 100, 51). To
your eye, it’s still the same orange. The change is below your perception
threshold.
The “least significant bit” of 50 is the one that flips between 50 and
51. Decimal 50 is binary 00110010; the 0 on the right is the LSB.
Flip it and you get 00110011, which is 51. The bit is “least
significant” because flipping it changes the number by exactly one,
whereas flipping the leftmost bit changes it by 128.
That one bit is the slot. We can put one bit of our data in there instead.
How many bits fit
A 512×512 sticker has 262 144 pixels. If we hide one bit per pixel — say, in the blue channel — that’s 32 768 bytes. Subtract some framing overhead and you have plenty of room for a few kilobytes of plaintext, which is many paragraphs of text or a small file.
You could be greedier and hide bits in all three channels, getting 3 bits per pixel. Or in the bottom two bits of each channel, for 6. Each of those is more capacity but also more visual deviation, and at some point your “innocent” image starts looking statistically weird. LSB-1 in one channel is a conservative choice. Stiger uses the blue channel, because the human eye is least sensitive to blue.
Why pixel order matters
The naive approach is to write your data starting at pixel 0 and going in row order. Easy to write, easy to detect: the first ~thousand pixels of the image have suddenly higher entropy than the rest, because random bytes don’t follow the smooth gradients of natural images.
The fix is to permute the pixel order using a key derived from the password. Instead of writing to pixels 0, 1, 2, 3…, you write to pixels 84372, 11, 200001, 99… — a deterministic shuffle that only the password-holder can reproduce.
Now the bytes are scattered evenly across the image, with no region that looks different from the rest. To anyone without the password, the order can’t be reproduced, so the bits read as random. To anyone with the password, the original ordering is recoverable trivially.
Why encryption on top
LSB-1 with permuted order hides the data from the eye and removes the obvious pattern. It does not, by itself, protect the data if someone guesses the technique and the key.
So in practice you encrypt the payload first — Stiger uses AES-256-GCM with PBKDF2-derived keys (600 000 iterations) — and only then embed the ciphertext into the LSBs. Now an attacker who guesses everything about the steganographic layout still gets a stream of bytes that look like noise without the password.
This is steganography + cryptography stacked. Cryptography hides what the bytes say. Steganography hides that there are bytes.
What breaks LSB steganography
Three things, all of them lossy operations on the carrier:
- Resampling. Resize the image, even by 1 pixel, and the LSB layer is gone — the new pixels are interpolated from the old, with no relationship to the original bits.
- Recompression. JPEG, in particular, throws away high-frequency detail, including LSB noise. PNG-to-JPEG re-encode destroys LSB-hidden data.
- Format conversion. Anything that touches the pixel values — a filter, a colour-space conversion, an “auto-enhance” — disturbs the LSBs.
The carrier has to survive unchanged from sender to receiver. This constrains where steganography is useful: chat platforms that recompress aggressively are bad carriers; ones that pass images through byte for byte are good. iMessage image attachments mostly are, but not on every path: group chats, cross-platform forwarding and saving to Photos before re-sharing may recompress them. Its native stickers are not carriers at all, they get re-encoded to HEIC — which is why Stiger sends attachments.
What this is not
LSB substitution is the textbook intro to steganography, not the state-of-the-art. There’s a whole field of steganalysis — statistical attacks designed to detect hidden bits in images, even with permuted ordering. Modern classifiers don’t need many samples or the original image: they can flag a single carrier with high accuracy, and forensic vendors ship them. Against anyone running these tools, LSB-1 is not invisible.
For Stiger’s use case — looking like a sticker to someone scrolling a chat or running a keyword scan — it’s enough. If your adversary runs forensic tooling on your phone, assume they can see that something is hidden — just not what, as long as the password holds.
The practical version of all of this: read the open spec and try the storyteller.