The BMPStegoFile class
The BMPStegoFile class lets you extract a hidden message from a 24-bit
.bmp stego file. It implements the IStegoFile interface that defines only a single
HiddenMessage property:
public interface IStegoFile
{
string HiddenMessage
{
get;
}
}
You use the
HiddenMessage property to access the hidden message. The BMPStegoFile class implementation starts like this:
public class BMPStegoFile : IStegoFile
{
private string fileName;
private string password;
private string hiddenMessage;
public BMPStegoFile(string fileName,
string password)
{
this.fileName = fileName;
this.password = password;
}
// Return the hidden message
public string HiddenMessage {
get
{
if (hiddenMessage==null)
ExtractHiddenMessage();
return hiddenMessage;
}
}
...
...
}
The class has three private fields:
- fileName the stego file name
- passwordthe password used to decrypt the message
- hiddenMessagethe hidden message
The
HiddenMessage property returns the value of the hiddenMessage field if it's not null; otherwise, it calls the
ExtractHiddenMessage method to extract the hidden message from the stego file.
Listing 2 shows the code for the
ExtractHiddenMessage method.
After opening the file and seeking to the end of the header (byte 54), the
ExtractHiddenMessage method shown in
Listing 2 calls
LSBHelper.Decode to get the first four bytes of the file, which, as you may remember, contain the length of the hidden message. Then, the method decrypts the length by calling
CryptoHelper.Decrypt passing the four bytes and the password.
At this point, it again invokes
LSBHelper.Decode to extract the full message. Then, something happens that may be a little obscure:
- The method again inserts the length as the first four bytes of the byte array buffer using the ConcatByteArray method.
- It decrypts the byte array with the CryptoHelper.Decrypt method.
- It extracts only the message (without the first four bytes of the buffer) via the GetByteMessage method.
The reason that inserting the length again is essential for decrypting the message is because the
BMPCoverFile.Encode method encrypts the length and the message together as a single block; therefore, due to the way the CryptoHelper class works, you must also decrypt the length and the message together to get the correct message.
Finally, the method sets the
hiddenMessage property to the Unicode string obtained from the bytes.