You are on page 1of 12

The Code Project

Title:

IMAGES' STEGANOGRAPHY Alaa Jebran

Author:

Introduction
Our goal is to build a simple application which is able to send and receive encrypted messages Which is also embedded inside images, the user has the right to choose the image he wants, and the program must tell If this image will suit the text or not, no pixel deformation is allowed and no size distortion is allowed (TIF images may Suffer size increment/decrement slightly, we will get to that later), the user can set different password for every Message he sends. This will enable the manager to transmit to two groups the same image but with two different passwords two different Messages.

Background
VB.NET, CRYPTOGRAPHY, Image Processing.

Using the code


I put the main procedure which will embed the text in the image the code is commented for every step: // // // If MsgBox("You are about to encrypt and embed this message :[[ " + TextBox1.Text + " ]] , Shall We Proceed?", MsgBoxStyle.OkCancel, "Stealth") = MsgBoxResult.Cancel Then Exit Sub // Label2.Text = "" // If RadioButton1.Checked = False And RadioButton2.Checked = False Then // MsgBox("Please select an extention") // Exit Sub // End If
file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (1 of 12)15/05/2007 06:34:00

The Code Project

// Dim text As String // text = TextBox1.Text.ToString + " " // Dim passw As String = "" input("Enter Password To Protect Your Text", passw) // If passw = "" Then 'err handler for ugly passwords // MsgBox("Error ! You Didn,t Choose Any Password To Protect The Message.") // Exit Sub // ElseIf passw.Length < 4 Then // MsgBox("Error ! Password Is Too Short.") // Exit Sub // End If // Dim amount As Double = text.Length // process_pass_with_tx(passw, text) ' this will encrypt the test by the password // 'this is done by generating a string from the password and this string is tall enough to perform // ' bit stream xor operation on all chares included in the message text that we want to send. // ' we secured the text ,now we will try hide the encrypted text in the image. // TextBox1.Text = text // If RadioButton1.Checked = True Then GoTo mode2 ''started deferences between tow modes here // If Me.OpenFileDialog1.ShowDialog = DialogResult.Cancel Then // Exit Sub // Else 'err handler to prevent wrong extensions // Dim infoReader As System.IO.FileInfo // infoReader = My.Computer.FileSystem.GetFileInfo(Me.OpenFileDialog1.FileName) // If infoReader.Extension.Substring(1, 3).ToLower <> (RadioButton2.Text.ToLower) Then // MsgBox("Error : Encryption mode requires different extension ") // Exit Sub

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (2 of 12)15/05/2007 06:34:00

The Code Project

// End If // LoadNewPict(Me.OpenFileDialog1.FileName) 'display the selected image preview // If PictureBox1.Image.Size.Width < 64 Or PictureBox1.Image.Size.Height < 64 Then 'prevent user from using unproperiate images // MsgBox("Error! Tiny Images Cann,t Be Used In Steganography.") // Exit Sub // End If // Dim w1 As Integer = PictureBox1.Image.Size.Width - 1 // Dim w2 As Integer = PictureBox1.Image.Size.Height - 1 // Dim possible_size As Double = ((w1 - 7) * (w2 - 7)) / 8 ' 8 bits make one char ,and avoid edges // If possible_size < amount Then 'determine if the image is not big enough for text // MsgBox("This image is not big enough to carry your message", MsgBoxStyle.Critical) // Exit Sub // End If // End If ' file dialog if // 'load accurding to extention // Dim dib, val, reslt As Integer // dib = FreeImage.FreeImage_Load(FreeImage.FREE_IMAGE_FORMAT.FIF_TIFF, OpenFileDialog1.FileName, 0) // On Error GoTo rongex1 // Dim ba As bits_array // ba.Initialize() // Dim sz As Long // Dim sz1, sz2, sz3, sz4 As Byte // Dim t As Double sz = text.Length ' number of chars to encrypt // // sz1 = Decimal.Remainder(sz, 100) ' take the lowest 2 digits of it // t = sz / 100 'take the left numbers (all except lowest 2 digits)
file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (3 of 12)15/05/2007 06:34:00

The Code Project

// sz = Decimal.Truncate(t) ''set size_variable to hold left numbers (all except lowest 2 digits) // sz2 = Decimal.Remainder(sz, 100) ' repeat // t = sz / 100 // sz = Decimal.Truncate(t) // sz3 = Decimal.Remainder(sz, 100) ' ' repeat

// t = sz / 100 // sz = Decimal.Truncate(t) // sz4 = Decimal.Remainder(sz, 100) ' will take final 2 digits, now you can see: the maximum size of text is ( 99 99 99 99 )

// 'now we will convert sz1 to bits array and stor it in the first line of the picture // 'after it we will do the sz2 and then sz3 and then sz4.. // 'the coming 4 for loops are used for that // Dim i, j, m // i = 0 // j = 1 // ba.Initialize() // byte_to_bits(sz1, ba) // For m = 0 To 7 '''''''''''''''''' 1 // i = i + 1 // FreeImage.FreeImage_GetPixelColor(dib, i, j, val) // ' set the lowest bit according to my bit // If odd(val) = True Then // If ba.bits(m) = False Then 'bit is zero

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (4 of 12)15/05/2007 06:34:00

The Code Project

// FreeImage.FreeImage_SetPixelColor(dib, i, j, (val + 1)) // End If // End If // If odd(val) = False Then // If ba.bits(m) = True Then 'bit is one // FreeImage.FreeImage_SetPixelColor(dib, i, j, (val + 1)) // End If // End If // Next m // ba.Initialize() // byte_to_bits(sz2, ba) // For m = 0 To 7 '''''''''''''''''''''' 2 // i = i + 1 // FreeImage.FreeImage_GetPixelColor(dib, i, j, val) // If odd(val) = True Then // If ba.bits(m) = False Then 'bit is zero // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If // If odd(val) = False Then // If ba.bits(m) = True Then 'bit is one // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If // Next m // ba.Initialize()
file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (5 of 12)15/05/2007 06:34:00

The Code Project

// byte_to_bits(sz3, ba) // For m = 0 To 7 '''''''''''''''''''''''''''' 3 // i = i + 1 // FreeImage.FreeImage_GetPixelColor(dib, i, j, val) // If odd(val) = True Then // If ba.bits(m) = False Then 'bit is zero // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If // If odd(val) = False Then // If ba.bits(m) = True Then 'bit is one // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If // Next m // ba.Initialize() // byte_to_bits(sz4, ba) // For m = 0 To 7 ''''''''''''''''''''''''''''' 4 // i = i + 1 // FreeImage.FreeImage_GetPixelColor(dib, i, j, val) // If odd(val) = True Then // If ba.bits(m) = False Then 'bit is zero // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (6 of 12)15/05/2007 06:34:00

The Code Project

// If odd(val) = False Then // If ba.bits(m) = True Then 'bit is one // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If // Next m '''' we have just stored the size of the text

// Dim n As Byte // Dim count As Long // count = 0 'i already set size ===>>> first line for size // ' Now i will scan the picture from the second line

// For j = 2 To PictureBox1.Image.Size.Height Step 1 // i = 1 // Do While (i + 7) < PictureBox1.Image.Size.Width ' Step 8 'may use freeimage_getdotspermeterx // n = Asc(CChar(text.Substring(count, 1))) 'this give ascii code for the every text letter, to reverse it use chr() function // count = count + 1 // If count = text.Length Then GoTo out // ba.Initialize() // byte_to_bits(n, ba) ''''''''''' // For m = 0 To 7 // FreeImage.FreeImage_GetPixelColor(dib, i, j, val) // ' change it according to my bit // If odd(val) = True Then // If ba.bits(m) = False Then 'bit is zero // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (7 of 12)15/05/2007 06:34:00

The Code Project

// End If // End If // If odd(val) = False Then // If ba.bits(m) = True Then 'bit is one // FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1) // End If // End If // i = i + 1 // Next m // i = i + 8 // Loop // Next j // out: // Dim fn As String // Dim con As Integer = 0 // fn = OpenFileDialog1.FileName + "_stealth.tif" // up1: // If File.Exists(fn) = False Then // FreeImage.FreeImage_Save(FreeImage.FREE_IMAGE_FORMAT.FIF_TIFF, dib, fn, &H800S) // Else // con = con + 1 // MsgBox("FILE: " + fn + " ALREADY EXISTS ,WE WILL CHANGE THE NAME TO " + OpenFileDialog1.FileName + con.ToString + "_stealth.tif") // fn = OpenFileDialog1.FileName + con.ToString + "_stealth.tif" // GoTo up1 // End If

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (8 of 12)15/05/2007 06:34:00

The Code Project

// Label2.Text = fn // Exit Sub // mode2: ' // ' in mode2 we will treat the file with the different extension in the same way ,just change the lib calls according to the extension // ' to decrypt the message we will reverse what we have done ///

Points of Interest
-You must put freeimage.dll in the same path of the exe to make it work. (Already done for u).

-The output image will be named the same as the input image plus "_stealth" ,if the output file already exists The program will handle that.

-The Textbox control has a maximum amount of chars to hold if your text is bigger than that, try to separate it and Use one image for each part.

- Lossy compression algorithms will damage encrypted data inside the image, so it is not recommended to compress the Output images before transmission.

- You may notice some size change for some images; probably this change will be ignored when compared to total file Size, this happens because compression algorithm that generated the native image that you supplied to the program is Different from the compression algorithm (in my dll lib) that generated the output image and not because embedded Data increased the size!!!
file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (9 of 12)15/05/2007 06:34:00

The Code Project

The proof is this: before you start the program write mini program and use the same function that I used in my code to Resave your Image in different name but in the same extension (let's say this new image is called beta). Now start our program and use it to embed some text, see the output image, it is exactly the same size of image beta.

Don't be surprised to know that some big agencies like CIA NSA... Use celebrities web sites or pornographic web

Sites to send and receive encrypted messages using similar technologies.

-Our way of Stenography is independent, you can use any encryption algorithm you trust (Public-Private key, ElGamal ...).

-My key generation was weak, I just repeated the key and this is obviously weak, (if any char in the key is discovered Then all message chars encrypted by it will be discovered), you may use good function to generate a big string to make The xor, or may be use a better cipher.

-You can use this program for authentication, by using a background image, in somewhere inside your application to set A copyright text.

-Our way of Stenography is independent from the bit sampling (bits per pixel) of images, but it is strongly Recommended to be used with 24 bpp images or higher, because this will guarantee the prevention of pixel Deformation, most of web images are sampled 24 bpp.

-The low order bits (this program) doesn't work with JPEG because it uses Lossy compression algorithm, working with JPEG requires extra work.

-You can take the red/green/blue channel of the image and do the same.

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (10 of 12)15/05/2007 06:34:00

The Code Project

-You can use this too: Take the channel whose histogram is approximated to horizontal line. Divide the new image to squares like this: 1 1 1 1 x 1 1 1 1 In the central pixel (x): put a value that is bigger than all neighbors if we got bit 1 Put a value that is smaller than all neighbors if we got bit 0.

Now the possible size to hold data here is divided on 9, and this way may cause slight distortion sometimes, because it Works on high order bits, we can only use the squares whose values are bigger than proper threshold.

-You can also use this: Divide the image to squares like this: XY YX If X's pixels hold the same value the square represents 1, change Y's pixels to be different. If Y's pixels hold the same value the square represents 0, change X's pixels to be different. If X's pixels and Y's pixels are different or both are the same then someone was playing with this image, and the bit is Invalid. We can apply this on more than one channel so if one is corrupted, we will use the backup.

_ last 2 algorithms: alaa jebran2007.

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (11 of 12)15/05/2007 06:34:00

The Code Project

History
Last updated: 5-10-2007

file:///H|/Documents%20and%20Settings/RAMBO/Desktop/bb/codeproject_template.html (12 of 12)15/05/2007 06:34:00

You might also like