Saturday, October 4, 2008

VLE distributed with c't Magazine

Few months back I had received a mail from the German c't tech magazine asking whether they can include my Vapour Liquid Equilibrium for Java (VLE) in their magazine's accompanying CD. I obviously said yes.

I got a surprise last week when I received the free copy of the magazine (issue number 17/2008) home delivered in India. The accompanying CD includes VLE v0.2. It was a bigger surprise to see the review of the software in the magazine along with a nice screenshot!

It is real joy know that people consider such amateur work to be worthy of distribution with magazine. Such things make spending personal time on open source software all the more worthwhile.

Wednesday, October 1, 2008

Added Debian Package for OpenStego for Easy Installation

Debian package for OpenStego v0.5.0 has been added in Sourceforge downloads.

Ubuntu (or any other Debian based distro) users can now just download that file and install by just double-clicking the icon for the downloaded ".deb" file. It can also be easily installed from command-line using:

$ sudo dpkg -i openstego-0.5.0-1.deb

Please let me know in case if anyone faces installation issues using this package.

Sunday, September 28, 2008

Support for Bulk Image Processing in OpenStego

OpenStego v0.5.0 has been released today, and it adds support to process multiple cover files in one go.

The "Cover File" box in the GUI now allows selection of multiple files. It also supports wildcard characters - '*' matches any number of characters and '?' matches exactly one character.

For example, if you want to embed a given message in all PNG files in "C:\test" folder for which the name starts with "image", then you can give Cover File value as:


This feature would be particularly useful when you are using OpenStego as watermarking solution. You can select all you images and embed your signature / copyright message in bulk.

Friday, March 14, 2008

Added RandomLSB algorithm support to OpenStego

Today, I released v0.4.2 of OpenStego. It has now support for one more algorithm - RandomLSB.
This is similar to the regular LSB algorithm except that instead of using Least Significant Bits of image in sequence, it writes in a pseudo-random order.

The random number generator is seeded using password hash. And so the sequence of bits written is dependent on the password.

This should now give a more robust method of embedding data, which will be difficult to detect using statistical analysis. The method is definitely slower compared to regular LSB algorithm, but is more secure.

Monday, February 11, 2008

Addition of Plugin Support in OpenStego

Today, I released OpenStego v0.4.0, with support for external plugins for steganographic algorithms. Most of the source files were restructured / refactored to provide this support.

New plugins can be added by implementing this abstract class from OpenStego:
  • net.sourceforge.openstego.OpenStegoPlugin
It consists of the following abstract methods:
  • getName(): This method should return a short name for the algorithm / plugin
  • getDescription(): This method should return a one line description of the algorithm / plugin
  • embedData(): This method should embed the given message into the given cover data and return back the stego data
  • extractMsgFileName(): This method should return the embedded message file name from the given stego data
  • extractData(): This method should return the embedded message data from the given stego data
  • canHandle(): This method should return true if this plugin can handle the given stego data
  • getReadableFileExtensions(): This method should return the list of file extensions that this plugin can read (where file is the coverfile)
  • getWritableFileExtensions(): This method should return the list of file extensions that this plugin can write (where file is the stegofile)
  • populateStdCmdLineOptions(): This method should populate the new command line options that it is going to handle
  • getUsage(): This method should return the help message to be displayed for this plugin
  • getEmbedOptionsUI(): This method should return an object which implements the net.sourceforge.openstego.ui.PluginEmbedOptionsUI class. This class extends the JPanel class. The object returned by this method is embedded inside the OpenStego GUI, when this plugin is selected
  • createConfig(): Three methods to create instance of OpenStegoConfig object (or its sub-class if this plugin extends the same)
OpenStego supports multiple languages and so, ideally, any new plugin added to OpenStego should also support the same. The following class can be used for handling multilingual labels:
  • net.sourceforge.openstego.util.LabelUtil
A new namespace should be added to LabelUtil class for each new plugin. Same namespace can also be used for exception messages while throwing OpenStegoException.

After implementing the OpenStegoPlugin class, create a new file named "OpenStegoPlugins.external" and put the fully qualified name of the new class in the file. Make sure that this file is put directly under the CLASSPATH while invoking the application.

That's all to adding new plugin for OpenStego.

Please refer to the "net.sourceforge.openstego.plugin.lsb" package sources for sample plugin implementation.

Wednesday, January 23, 2008

Usage of OpenStego in LOST

OpenStego was used to embed some secret message in an image by the creators of the alternate reality game LOST (

The data was password protected, because of which I got a huge number of queries on how to find out the password from the stegged file. This is the reply that I have:

"There is no way to get back the password from the stegged data. Problem is that the password is first hashed using MD5 - which a is one-way algorithm. This means that getting back the password is next to impossible. Only option is to use brute-force hacking of the password."

Lot of people tried varied range of passwords manually. One thing they found out was that OpenStego was accepting "README.txt" as password, but it was throwing some other exception related to GZIP. The problem is that the "PBEwithMD5andDES" algorithm accepts wide range of passwords for decryption - only thing is that it would generate garbage if password is wrong. Now as the data gets compressed first using GZIP before encrypting, while decrypting if wrong password is given (which matches the padding and so doesn't give Invalid Password message), then garbage data is generated. And when OpenStego tries to decompress it using GZIP, it gives GZIP exception because of wrong data.

Going by LostPedia, it can be seen that people have finally found out the actual password from other clues in the game.

I am going to update OpenStego, so that if GZIP exception is encountered then it will give a message: "Either the embedded data is corrupt, or invalid password was provided".

One good thing was that OpenStego got good amount of publicity due to LOST game.

Thursday, January 17, 2008

Website for OpenStego

I had created a very simple single-page website for OpenStego which was bare minimum, and was not very clean on how and why OpenStego should be used.

I was revamping it for past two days, and today I have published the same. It can be accessed at It includes the following now:
  • What is Steganography
  • Using OpenStego GUI
  • Using OpenStego from Command-line
  • Features and ToDo List
  • Full changelog since v0.1.1
Please visit the same and let me know if you feel it needs something more / less.

Thursday, January 10, 2008

Cryptography support in OpenStego

Cryptography support in OpenStego is pretty straightforward. It directly uses the Cryptography support provided by Sun's JRE which was added starting with version 1.4. Thus OpenStego will need at least JRE 1.4 to run.

javax.crypto.Cipher class is used for cryptography. PBEWithMD5AndDES is the algorithm used for encryption (Password based encryption which uses MD5 hash of the password to generate the key for DES which does actual encryption).

I would like to add support for other algorithms like AES, but I think, as of now, DES support is enough.

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.

Wednesday, January 2, 2008

About Vapour Liquid Equilibrium project

I studied chemical engineering at the university. During that time, I had created a C program for performing Vapour Liquid Equilibrium (VLE) calculations (along with support to generate graphs). It was coded in Turbo C++ on DOS.

After graduating from the university, I got to know about open-source and felt that I should publish it on Sourceforge. Thus, my first open-source project came into existence. I converted the C code to Java, cleaned it up, and added documentation. The code is now well structured with support for easy extension.

VLE calculations involve two main things:
  • Calculating Activity coefficient
  • Calculating Fugacity coefficient
There are wide variety of methods available for calculating both of these. To keep the rest of the calculations generic, I first created Java interface files for Activity and Fugacity calculations (IActivityCalculator and IFugacityCalculator). For each method of calculation, we can implement these interfaces, and just update configuration files ( / to add the support for new method.

Currently, I have included support for:

Activity Calculators
  1. Margule's Equations
  2. Van Laar's Equations
Fugacity Calculators
  1. Virial Equations
  2. Redlich-Kwong Equation
  3. Peng-Robinson Equation
New methods like UNIFAC, UNIQUAC, Wilson-NRTL, etc. can be added easily. I have lost touch with Chemical Engineering, and so it seems that there won't be any further updates to this project from my side.