// steganography · aes-256-gcm · in your browser

Hidden in the grain.

Status: Ticker (placeholder, no token exists):
Key derivation
PBKDF2-SHA256 · 600,000 rounds
Cipher
AES-256-GCM
Carrier
1 LSB per R, G, B
Network
None — runs offline
// the darkroom

Expose a note. Develop it back.

Left: hide an encrypted note in a picture and save it as PNG. Right: load that PNG and the passphrase to read the note again. Every number below is measured on your actual image.

EXPOSE Hide a note in an image

Pick a PNG or JPG (or generate a test frame). It is decoded to raw pixels; transparency is flattened onto white, and anything over 3000 px on its long side is scaled down.

Load an image to see its capacity.
  • Only the PNG survives. Re-saving as JPG, or sending through chat or social apps that re-compress or resize, wipes the hidden bits. Send it as a file, not a photo.
  • It can be detected. Steganalysis (chi-square, RS analysis) can often tell that an image carries LSB data, even though it can't read it without the passphrase.
  • Never store a real seed or private key for a wallet that holds funds — here or in any image.

DEVELOP Read a note back

Load a PNG made by Pixelsafe and enter its passphrase. A wrong passphrase, a different image, or a re-compressed copy all fail the same way: nothing comes out.

Recovered note

Note text, passphrases and pixels exist only in this tab's memory. “Wipe fields” clears the inputs and buffers we control; JavaScript cannot guarantee strings are erased from memory, so close the tab when done.

// how it works

Encrypt first, then hide

  1. Derive a key. A fresh random 16-byte salt and your passphrase go through PBKDF2-SHA256 with 600,000 iterations, producing 36 bytes: a 256-bit AES key and a 4-byte length mask. The high iteration count makes each passphrase guess slow for an attacker.
  2. Encrypt. The note (UTF-8) is sealed with AES-256-GCM under a random 12-byte IV. The 32-byte header is bound in as additional authenticated data, so changing any header or ciphertext bit makes decryption fail instead of returning garbage.
  3. No plaintext marker. There is no magic “PIXELSAFE” tag. Salt and IV are random, the length is XOR-masked with key material, and ciphertext is indistinguishable from random — so reading the LSBs without the passphrase yields only noise.
  4. Embed. The bytes are written bit by bit, most significant first, into the lowest bit of each R, G and B value, pixel by pixel from the top-left. Alpha is never touched. Each channel changes by at most 1 out of 255 — and only where its bit differed, about half the time.
  5. Save losslessly. The canvas is exported as PNG, then immediately decoded again and run through extraction with your passphrase — the round-trip check confirms the file you download actually opens.
salt16 bytes
iv12 bytes
len ⊕ mask4 bytes
AES-GCM ciphertext + 16-byte tagnote length + 16

Capacity = ⌊width × height × 3 ÷ 8⌋ bytes, minus 48 bytes of overhead (32 header + 16 tag).

// privacy model

What someone holding the image can learn

Without the passphrase

  • The picture, which looks unchanged to the eye
  • That it is a PNG — sometimes itself a hint, if a JPG would be normal
  • Statistical traces of LSB embedding, if they run steganalysis
  • Nothing about the note's content; not even its exact length

With the passphrase

  • The full note. Anyone who learns or guesses the passphrase can read it
  • A weak passphrase can be brute-forced offline — PBKDF2 slows guessing but doesn't stop it
  • Use a long, unique passphrase (5+ random words) and keep it separate from the image

Known limitations — please read

  • Fragile by design. Any re-encoding destroys the message: JPG/WebP conversion, resizing, cropping, filters, screenshots, and almost every chat and social upload. Keep the original PNG and send it as a file.
  • Detectable. Sequential 1-bit LSB embedding is the most-studied form of steganography; standard tools can often flag the image as carrying data. Pixelsafe hides the content, not reliably the existence of a message. It reduces exposure — it does not provide anonymity or deniability.
  • The passphrase is everything. There is no recovery. Forget it and the note is gone; choose a weak one and it can be guessed offline.
  • Not for seed phrases or private keys. Never store a real seed phrase or key of a wallet holding funds here or in any image. Pixelsafe refuses text that looks like a 12–24 word seed phrase or a Solana secret key, but that check is a heuristic, not a guarantee.
  • Browser quirks can break it. Some privacy modes (e.g. canvas fingerprinting protection in Brave, Safari or Firefox's resistFingerprinting) add noise to canvas reads, which corrupts the hidden bits. The round-trip check catches this — if it fails, use a different browser profile.
  • Experimental and unaudited. Built on the browser's Web Crypto API; no third party has reviewed this code. There is no program, token or on-chain component.