Steganography: Simple Implementation in C#: Hamzeh Soboh
Steganography: Simple Implementation in C#: Hamzeh Soboh
Introduction
Steganography is the art and science of hiding information by embedding messages within others.
Steganography works by replacing bits of useless or unused data in regular computer files with bits of different,
invisible information. This hidden information can be plain text, cipher text, or even images [*] .
I've implemented two main methods for that purpose: embedText and extractText. You can find the full
and documented code with a running example attached to this tip.
The least significant bit (LSB) is the bit that when flipped from 0 to 1 or from 1 to 0, then no significant change
will occur on the total value. It's the bit on the rightmost, that when flipped, the value will be only affected by 1 to
be 100 instead of 101. This means that the image will not be significantly affected when we reserve this bit for our
purpose. Where the most significant bit (MSB) is bit on the leftmost, that when flipped, the value will be affected
by 128 (1x27) to be 229 instead of 101.
When we try to hide our data in an image (as in our case), then we need enough budget of LSBs to hide our data
in. These bits are located in the image pixels. Since each pixel has three elements (R, G, and B that represent the
Red, Green, and Blue elements of the pixel consecutively, assuming non-transparent image), each of these
elements can have a value between 0 and 255. Now, assume that the image was 300 pixels width by 400 pixels
height, then we'll have 300 x 400 x 3 = 360000 LSBs. And as each character can be represented by 8 bits, then
that image can hide 360000 / 8 = 45000 characters!
Step by Step
It's more simple than hiding. Just pass through the pixels of the image until you find 8 consecutive zeros. As you
are passing, pick the LSB from each pixel element (R, G, B) and attach it into an empty value. When the 8 bits of
this value are done, convert it back to character, then add that character to the result text you are seeking.
// holds the number of trailing zeros that have been added when finishing the
process
int zeros = 0;
// now, clear the least significant bit (LSB) from each pixel element
R = pixel.R - pixel.R % 2;
G = pixel.G - pixel.G % 2;
B = pixel.B - pixel.B % 2;
// check which pixel element has the turn to hide a bit in its LSB
switch (pixelElementIndex % 3)
{
case 0:
{
if (state == State.Hiding)
{
// the rightmost bit in the character will be
(charValue % 2)
// to put this value instead of the LSB of the pixel
element
// just add it to it
// recall that the LSB of the pixel element had been
cleared
// before this operation
R += charValue % 2;
charValue /= 2;
}
} break;
case 2:
{
if (state == State.Hiding)
{
B += charValue % 2;
charValue /= 2;
}
pixelElementIndex++;
if (state == State.Filling_With_Zeros)
{
// increment the value of zeros until it is 8
zeros++;
}
}
}
}
return bmp;
}
colorUnitIndex++;
return extractedText;
}
n /= 2;
}
return result;
}
}