How to steganography decoder for png and bmp
- Step 1Open the decoder on the Developer plan — Steganography Decoder is gated to the Developer tier. Once signed in, you can process files up to 2 GB, one image at a time (the tool does not accept batches).
- Step 2Drop a suspect PNG or BMP — The file picker accepts
.jpg .jpeg .png .gif .bmp .webp, but only lossless carriers (PNG, BMP) preserve LSB data. Use a PNG or BMP recovered as-is, not a re-saved or screenshotted copy. - Step 3Run the extraction — The image is drawn to an off-screen canvas and
getImageDatareturns the raw pixel array. The tool walks R, G, B low bits across every pixel and assembles bytes. - Step 4Read the recovered text — If a null-terminated payload exists, it appears in the output panel. If nothing valid is found, the tool returns the literal string
(no LSB-encoded message detected). - Step 5Judge whether the payload is itself encrypted — Readable text means a plaintext payload. High-entropy bytes that look like noise suggest the hidden data was encrypted before embedding — confirm with the Entropy Analyzer.
- Step 6Export for the case file — Download
extracted-message.txt, then fingerprint it with the Multi-Hash Fingerprinter so the extracted artefact has a recorded hash in your evidence log.
What the decoder actually reads
Behaviour is fixed in lib/security/security-processor.ts (decodeLsb). There are no options to configure — the algorithm below is what runs every time.
| Step | What the tool does | Why it matters for forensics |
|---|---|---|
| Load | Reads the file into a Blob URL and decodes it with the browser image decoder onto a canvas | Decoding happens locally; the evidence file is never transmitted |
| Channel scan | Iterates pixels with stride 4 (RGBA) but only reads data[i] & 1, data[i+1] & 1, data[i+2] & 1 — alpha is ignored | Payloads written to alpha won't be found; standard encoders use R/G/B only |
| Order | Strict raster order: row 0 left-to-right, then row 1, and so on | Must match the encoder's order; reversed or column-major payloads won't decode |
| Byte assembly | Groups bits into 8-bit chars MSB-first via parseInt(bits, 2) then String.fromCharCode | Bit-endianness must match the encoder; this is byte-level (Latin-1), not UTF-8 decoding |
| Terminator | Stops at the first byte equal to 0x00 | Anything after a stray null is dropped; a payload with no null runs to the cap |
| Cap | Hard limit of 100,000 output characters | Prevents a non-steg image from streaming millions of garbage bytes |
Carrier format suitability
The UI accepts six image extensions, but LSB only survives lossless pixels. Lossy or recompressed carriers will not return a valid payload.
| Format | Accepted by picker | LSB survives? | Forensic verdict |
|---|---|---|---|
| PNG | Yes | Yes (lossless) | Primary carrier — examine first |
| BMP | Yes | Yes (uncompressed) | Reliable carrier — examine |
| GIF | Yes | Partial — palette/indexing can disturb LSBs | Decodes, but treat results cautiously |
| WebP (lossless) | Yes | Yes if encoded lossless | Possible carrier; verify it isn't lossy WebP |
| JPEG | Yes | No — DCT compression destroys the LSB plane | Will return no payload; not a format error, just empty |
Cookbook
Real first-pass extraction scenarios an examiner meets when triaging suspect images. The decoder is fixed-function — these show how to read its output, not how to configure it.
Clean extraction from a PNG carrier
A PNG seized from a device decodes to a short null-terminated string. This is the textbook positive result.
Input: evidence-042.png (1280×720 PNG, lossless) Action: drop into Steganography Decoder Output panel: meet at the usual place 21:00 Downloaded as: extracted-message.txt Next: hash extracted-message.txt with the Multi-Hash Fingerprinter for the log
No payload present
An ordinary photo with no embedded data. The tool walks the LSB plane, never builds a valid null-terminated string, and returns its literal empty-result sentinel.
Input: holiday.png (ordinary photo, no steg) Output panel: (no LSB-encoded message detected) Reading: no standard LSB payload exists in R/G/B raster order. This is a clean negative — not an error.
Garbled output = encrypted payload
A null terminator is found, but the bytes before it are high-entropy noise. The carrier holds a payload that was encrypted before embedding.
Input: profile-pic.png Output panel: \x9f\x12\xc4\x00\x7a\xe8 ... (non-printable, random-looking) Reading: payload exists but is ciphertext. Confirm: Entropy Analyzer on extracted-message.txt → near-8.0 bits/byte The plaintext is behind a key you do not have.
JPEG returns nothing — not a warning
Investigators often expect a 'JPEG not supported' message. There is no such warning. The JPEG decodes, but its DCT compression has already wiped the LSB plane, so no valid payload assembles.
Input: shared-image.jpg Output panel: (no LSB-encoded message detected) Reading: JPEG was accepted and processed, but lossy compression destroyed any LSB data. Re-examine the original lossless source if one exists.
Round-trip verification with the encoder
To validate the tool on a known sample before trusting it on evidence, encode a known string, then decode it back.
1. Steganography Encoder: carrier test.png + message 'forensic check 7Q' → download test-steg.png 2. Steganography Decoder: drop test-steg.png → Output: forensic check 7Q Exact round-trip confirms the bit order and terminator behaviour.
Edge cases and what actually happens
JPEG carrier
No payload (by design)The picker accepts .jpg/.jpeg, so the file is decoded and scanned — there is no 'unsupported format' warning. JPEG's lossy DCT compression rewrites pixel values, so any LSB payload is already gone. Expect (no LSB-encoded message detected). If you have the original lossless source, examine that instead.
Payload embedded in the alpha channel
MissedThe decoder only reads data[i], data[i+1], data[i+2] (R, G, B). The alpha byte data[i+3] is skipped. A tool that hid data in alpha will produce nothing here — this is a known blind spot of the R/G/B-only algorithm.
Carrier re-saved or screenshotted
No payloadOpening a steg PNG and re-exporting it (or screenshotting it) re-quantises pixels and rewrites the LSB plane. The payload is destroyed even though the file is still a PNG. Always work from the original recovered bytes — verify them with the Multi-Hash Fingerprinter.
Payload has no null terminator
Runs to capIf the embedded data was not null-terminated, the decoder keeps reading LSBs until it hits the 100,000-character cap or the end of the pixel data, returning the message plus trailing noise. Treat unusually long output as suspect.
Non-UTF-8 / binary payload
Shown as bytesBytes are mapped through String.fromCharCode one byte at a time — this is Latin-1-style, not UTF-8 decoding. A multi-byte UTF-8 message appears as mojibake. Capture the raw extracted-message.txt and decode it as UTF-8 in a separate step if needed.
Very large 2 GB carrier
SupportedDeveloper-tier file limit is 2 GB. The whole pixel array is read into memory for the canvas, so an extreme carrier can be memory-heavy in the tab — but it is within the documented limit.
Multiple files dropped
One at a timeThe decoder sets acceptsMultiple: false. It processes a single image; there is no batch mode. Run carriers individually.
Bit order reversed by the source tool
GarbledThis decoder assembles bytes MSB-first in R→G→B raster order. A foreign encoder that wrote LSB-first, or BGR order, will decode to garbage. A clean round-trip with the JAD Steganography Encoder is the reference behaviour.
Corrupt or unreadable image
Failed to load imageIf the browser image decoder cannot parse the file, loadImage rejects with 'Failed to load image' and no extraction runs. Confirm the bytes are a real image with the Magic-Byte Validator.
Free or Pro account
Tier lockedThe tool's minTier is developer. Free, Pro, and Pro+Media accounts see the upgrade overlay rather than the processor. Forensic use assumes a Developer plan.
Frequently asked questions
Which channels does the decoder read?
Only the low bit of the Red, Green and Blue channel of each pixel — three bits per pixel. The alpha channel is skipped entirely. This matches what the JAD Steganography Encoder writes.
In what order are the pixels read?
Strict raster order: the first row left-to-right, then the next row, to the bottom of the image. Bytes are assembled most-significant-bit first. A foreign tool using a different order will not decode correctly.
Why did my JPEG return no message?
JPEG uses lossy DCT compression that rewrites pixel values, destroying any low-bit payload. The file is still accepted and processed — there is no error — but no valid payload can be reconstructed. LSB only survives lossless PNG and BMP.
What does '(no LSB-encoded message detected)' mean?
That literal string is returned when the decoder finds no valid null-terminated payload in the R/G/B LSB plane. It is a clean negative result, not an error. The image either holds no LSB data or used a method this tool doesn't read.
Is the image uploaded anywhere?
No. The file is read into a local Blob URL, decoded on an in-page canvas, and processed entirely in your browser. Nothing is transmitted, which is essential when the carrier is evidence.
What's the maximum payload size returned?
Output is hard-capped at 100,000 characters. If a payload is longer, or there's no terminator, the decoder stops at the cap. Most LSB messages are far smaller.
The output looks like random bytes — what happened?
A null terminator was found but the bytes before it are high-entropy. That usually means the payload was encrypted before embedding. Run the extracted text through the Entropy Analyzer; a value near 8.0 bits/byte confirms ciphertext.
Can it detect steghide, F5, or DCT steganography?
No. This is an LSB-plane decoder for PNG/BMP. Methods like F5, steghide, and JPEG-DCT embedding need dedicated forensic tools. Use this for a fast first pass on the most common amateur technique.
Does it accept more than one file at a time?
No — acceptsMultiple is false. Process one carrier per run. There is no batch or folder mode in this tool.
What tier do I need?
The Developer plan. The tool's minimum tier is developer, giving a 2 GB file limit. Lower tiers see an upgrade overlay instead of the processor.
How do I verify the tool before using it on a case?
Run a round-trip: hide a known string with the Steganography Encoder, download the PNG, then decode it here. Getting the exact string back validates the bit order and terminator handling on your machine.
What file name does the download use?
The extracted payload downloads as extracted-message.txt. Hash it with the Multi-Hash Fingerprinter so the artefact has a recorded fingerprint in your evidence log.
Privacy first
Every JAD Security operation runs entirely in your browser. Files, passwords, and PGP private keys never leave your device — verified by zero outbound network requests during processing.