TIER FORGE IS ONLINE: CONSTRUCT AND VISUALIZE RANKED DATA SETS WITH DRAG-AND-DROP PRECISION. ACCESS AT /APPS/TIER-FORGE.

See Tier Forge
Back to IntelSOURCE: dev

Steganography: Hiding Secrets in Plain Sight with LSB

Steganography is the art and science of hiding information within other non-secret data. Unlike cryptography, which scrambles a message so it can't be read, steganography hides the very existence of the message.

In this deep dive, we'll explore the implementation of the Steganography Tool added to Fezcodex, focusing on the Least Significant Bit (LSB) technique.

The Core Concept: Least Significant Bit (LSB)

Digital images are made up of pixels. In a standard 24-bit RGB image, each pixel has three color channels: Red, Green, and Blue. Each channel is represented by 8 bits (a value from 0 to 255).

Example of a pixel's color:

  • Red: 10110101 (181)
  • Green: 01100110 (102)
  • Blue: 11001011 (203)

The Least Significant Bit is the rightmost bit in these binary strings. If we change this single bit, the decimal value of the color channel only changes by 1. For example, changing the Red channel from 10110101 (181) to 10110100 (180) is a change so subtle that the human eye cannot detect it in a complex image.

By replacing the LSB of each color channel with a bit from our secret message, we can embed data directly into the image.

The Protocol: FEZ Steganography

To make the extraction process reliable, we've implemented a simple protocol:

  1. Magic Header (FEZ): The first 24 bits (3 bytes) of the hidden data always spell "FEZ". This allows the decoder to verify if an image actually contains a hidden message from our tool.
  2. Length (32-bit): The next 32 bits represent the length of the message in bytes. This tells the decoder exactly when to stop reading.
  3. The Message: The remaining bits are the actual UTF-8 encoded message.

Tracing the Magic: Encoding "FEZ"

Let's look at how the magic header FEZ is scattered across the first few pixels.

Step 1: Convert characters to binary

  • F (70): 0 1 0 0 0 1 1 0
  • E (69): 0 1 0 0 0 1 0 1
  • Z (90): 0 1 0 1 1 0 1 0

Combined Bitstream: 01000110 + 01000101 + 01011010 (24 bits total)

Step 2: Embed into pixels Since each pixel has 3 channels (R, G, B), we need 8 pixels to hide these 24 bits.

PixelChannelOriginal ByteBit to HideModified Byte
Pixel 1Red101101010 (from F)10110100
Green011001101 (from F)01100111
Blue110010110 (from F)11001010
Pixel 2Red010101000 (from F)01010100
Green111100110 (from F)11110010
Blue001100111 (from F)00110011
Pixel 3Red101010101 (from F)10101011
Green110011010 (from F)11001100
Blue000111100 (from E)00011110
Pixel 4Red101100101 (from E)10110011
Green011011010 (from E)01101100
Blue111000110 (from E)11100010
Pixel 5Red010101010 (from E)01010100
Green111100101 (from E)11110011
Blue001100110 (from E)00110010
Pixel 6Red101010101 (from E)10101011
Green110011010 (from Z)11001100
Blue010111101 (from Z)01011111
Pixel 7Red101100110 (from Z)10110010
Green011011001 (from Z)01101101
Blue111000111 (from Z)11100011
Pixel 8Red010101010 (from Z)01010100
Green111100101 (from Z)11110011
Blue001100110 (from Z)00110010

By the time we reach Pixel 8, all 24 bits of "FEZ" are woven into the image. If you open this in a hex editor, you might see that the color 181 became 180, but the text "FEZ" is nowhere to be found in the raw bytes!

Why PNG and not JPEG?

Our tool works best with PNG files. Why?

  • PNG (Portable Network Graphics) is a lossless format. It preserves every single bit exactly as it was saved.
  • JPEG (Joint Photographic Experts Group) is a lossy format. It uses compression algorithms that slightly alter pixel values to reduce file size. These tiny changes are fine for human viewing, but they destroy the data we've hidden in the LSBs.

The Implementation (JavaScript/Canvas)

We use the HTML5 <canvas> API to access and manipulate image data at the pixel level.

Encoding Logic

DATA_NODE: javascript
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; // Uint8ClampedArray [R, G, B, A, R, G, B, A, ...] // ... transform message to bits ... let bitIndex = 0; for (let i = 0; i < data.length && bitIndex < allBits.length; i += 4) { for (let j = 0; j < 3 && bitIndex < allBits.length; j++) { // Replace LSB of R, G, or B // (data[i + j] & 0xfe) clears the last bit // | allBits[bitIndex++] sets it to our secret bit data[i + j] = (data[i + j] & 0xfe) | allBits[bitIndex++]; } } ctx.putImageData(imageData, 0, 0);

Decoding Logic

Decoding is the reverse process. We iterate through the pixels, extract the LSB of each R, G, and B channel, and rebuild the bitstream until we've parsed the header, the length, and finally the message content.

Challenges and Limitations

  • Capacity: The amount of data you can hide depends on the image resolution. Each pixel can hold 3 bits (1 for each RGB channel). A 1080p image (1920x1080) can theoretically hold about 777 KB of hidden data.
  • Robustness: LSB steganography is very fragile. Resizing, cropping, or re-saving the image as a JPEG will likely corrupt the hidden message.
  • Security: Pure LSB is "security through obscurity." Anyone who knows the technique can extract the message. For true security, you should encrypt the message before hiding it in the image.

Try it out!

Check out the Steganography Tool in the Applications section and start sending your own cryptic signals through the digital aether.

// INTEL_SPECIFICATIONS

Dated12/01/2026
Process_Time6 Min
Categorydev

// SERIES_DATA