Friday, January 4, 2008

OpenStego: Stint with Steganography

I got first interested in Steganography while reading the novel Cryptonomicon by Neal Stephenson. It talked about hiding data using the lowest bit of the color data of pixels in the picture. Concept is fairly simple, and I was able to quickly implement it using Java. Thus, OpenStego project came into existence.

The core of the application are two classes: StegoInputStream and StegoOutputStream. Implementing the steganography routine as streams helped a lot in keeping the design simple.

StegoOutputStream is used to write the message into the cover (source image) file. Here are the steps:
  • On initialization, we need to provide the length of the data that we want to embed in the image.
  • Based on this length, first it tries to calculate how many bits are required per pixel per color channel. As OpenStego supports only 24bpp images, we have maximum of 8 bits per color channel that we can use. But if data uses more that 3 bits, the original image will start loosing its color data, and it becomes easy for someone to find out that something is hidden inside the image.
  • It creates the header data, which includes Magic String for OpenStego, number of bits used per channel, name of the message file, and other stuff like whether compression is used or not, whether data is encrypted or not, etc.
  • This header data is prefixed to the original message data, so that it gets written first.
  • After determining number of bits required per channel, it starts embedding data one byte at a time. For each input byte, it breaks it up in group of number of bits determined, and then updates the pixel's color value accordingly (lowest bits are updated).
  • It maintains the position of the last pixel / color / bit that was updated, so that data for next byte is updated from there onwards.
StegoInputStream is used to read the data back from the image. Following steps are used:
  • Data is read from the image one byte at a time.
  • First the header data is read and it is determined whether the image is a valid stego file or not (based on the existence of Magic String for OpenStego).
  • The header data also contains the number of bits that were used per color channel while embedding the data.
  • Based on the number of bits per color channel, that many number of lowest bits are read from each color channel of each pixel.
  • Again, the position of the last pixel / color / bit that was read is maintained, so that data of next byte can be read from there onwards.
I'll talk about encryption of data in the next blog.

5 comments:

Aashish said...

hello samir ...

i'm ashish mishra in my ifnal year of me btech ..i'm working on steganography. i have gone through your profile and you have mentioned there that u have implemented the code in java so could u please provide me with its code .please..

Aashish said...

hello samir ...

i'm ashish mishra in my ifnal year of me btech ..i'm working on steganography. i have gone through your profile and you have mentioned there that u have implemented the code in java so could u please provide me with its code .please..

Samir Vaidya said...

Download from http://openstego.sourceforge.net. The ZIP file contains both JAR as well as sources.

Unknown said...

The Steganography project uses manipulation of least significant bits in each colour channel. But Java doesnot support bit level interaction then how is it carried out is there in JNI so that bit level trasformation is done

Samir Vaidya said...

Java does support bit level interaction! please check out the code