Picture is Worth 1000 Words
About a year ago, I was sick as a dog. I caught some sort of child generated
disease which is common to anyone with small kids that go to pre-school. Anyhow
while on cough medicine I thought it would be fun to explore steganography.
When I went to college I had a cryptography course in which the professor threw
two nearly identical images on the board. He asked the class, what is different
between the two images? People were confused by the question and started
rattling off various things, like well, the hue is slightly different, or one is
more blocky than the other, or maybe the compression was different. Then he let
loose the real answer, and said, the one on the right has the entire contents of
Moby Dick within it.
At that point in time, my mind was blown. Wow! You can actually hide data, and mask data within other data. The professor mentioned that a common approach for hiding data within an image is to hide the data within low order bits of the the color values of each pixel, as those low order bits really don’t add too awful much to the color of the particular pixel.
Not sure why I got motivated last year to try and implement a simplistic program but here is what I was thinking:
- Iterate over every pixel.
- Break each pixel into 4 colors (Red, Blue, Green, Alpha)
- Take 2 bits of every RBGA color byte and stuff my data in the LSBs
- Denote an end of hidden document pixel
- Break up my input data into chars
- Put 2 bits of every input byte into each color byte of the pixel
Here is the basic implementation:
Reading in the input image, and then iterating over the bounds, we can break the image into RGBA color codes. The real interesting part is the binary operations we can do to make the bits in the byte:
We are shifting our message char 6 bits to the right, converting it to an unsigned 32 bit int, and then adding our red color value after masking off the lower 2 bits. Same with the Blue, except we are shifting 4, and masking out everything that isn’t the last two bits. Think about it like this:
Then to finish up we set our new image color value to these color values. At the end of the secret message we set a completely empty color pixel on the image so we know where the data stops.
Pretty fun little project. Full Gist Here!
Hope this was helpful to anyone.