Sunday, 3 November 2013

Steganography - Hiding information inside a Image

        In this article , we are going to see how to hide the information inside the image to do this we have understand about the Steganography concepts well. Steganography is the art of hiding information by embedding information in to others. This replace the bits of unused data in computer files with bits of information. This information can be text ,cipher text and image.

   I have decided to share some information through mail to another person but it should not explicity seen by any one, when seen explicity it shown different information. simply said in facebook i have to post some images ,any end user seen it seems as only photo, but my end user downloads the photo and extract information hide in that photo, now we see how to do that.

   First the data hiding in image is should be secure, so we are going to implement an Rijendal algorithm which will encrypt the data based on password and decrypt the data with same password. this is symmetric algorithm i.e. same password must be use for encryption and decryption

Download Hiding Information : Click here to download exe
Prerequisites : Dotnet Framework 4.0 should be there in Computer [Download from web] , otherwise it should be windows 7 OS.


   Output:











Code in C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;

namespace DataHiding
{
    public partial class Form1 : Form
    {
        Bitmap img = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void label1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog openfile = new OpenFileDialog();
            openfile.Filter = "Text files (*.txt)|*.txt";
            openfile.Multiselect = false;
            openfile.ShowDialog();
            if (!String.IsNullOrEmpty(openfile.FileName))
            {
                Information.Text = File.ReadAllText(openfile.FileName);
            }
        }

        private void toolStripLabel1_Click(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {
            RMessagebox msg = new RMessagebox("About", "By: Rajesh G © 2013");
            msg.ShowDialog();
        }

        private void Form1_Load(object sender, EventArgs e)
        {         
            Result.Text = "";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openfile = new OpenFileDialog();
            openfile.Filter = "Image Files (*.jpeg; *.png; *.bmp)|*.jpg; *.png; *.bmp";
            openfile.Multiselect = false;
            openfile.ShowDialog();
            if (!String.IsNullOrEmpty(openfile.FileName))
            {
                hideimage.BackgroundImage = Image.FromFile(openfile.FileName);
            }
            Password.Text = "";
            Information.Text = "";
        }

        private void button4_Click(object sender, EventArgs e)
        {
            img = (Bitmap)hideimage.BackgroundImage;
            string extractString = SteganographyHelper.ExtractText(img);
            if (string.IsNullOrEmpty(Password.Text))
            {
                MessageBox.Show("Please specify the password, To Extract the information.","Security");
                return;
            }
            try
            {
                extractString = RijndaelAlgo.Decrypt(extractString, Password.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Wrong password", "Error");
                return;
            }
            Information.Text = extractString;
            MessageBox.Show("Information Extracted successfully", "Information");
        }

        private void button3_Click(object sender, EventArgs e)
        {
            img = (Bitmap)hideimage.BackgroundImage;
            string embtext = Information.Text;

            if (string.IsNullOrEmpty(embtext))
            {
                MessageBox.Show("Empty string can't be hide", "Warning");
                return;
            }

            if (string.IsNullOrEmpty(Password.Text))
            {
                MessageBox.Show("Password can't be empty", "Warning");
                return;
            }

            try
            {
                embtext = RijndaelAlgo.Encrypt(embtext, Password.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            img = SteganographyHelper.MergeText(embtext, img);

            SaveFileDialog sav = new SaveFileDialog();
            sav.Filter = "Png Image|*.png|Bitmap Image|*.bmp";

            if (sav.ShowDialog() == DialogResult.OK)
            {
                switch (sav.FilterIndex)
                {
                    case 0:
                        {
                            img.Save(sav.FileName, ImageFormat.Png);
                        }break;
                    case 1:
                        {
                            img.Save(sav.FileName, ImageFormat.Bmp);
                        } break;
                }
            }

            MessageBox.Show("Information hided successfully", "Information");
            hideimage.BackgroundImage = null;
            Information.Text = "";
            Password.Text = "";
        }
    }
}



Code for Stegnography:

using System;
using System.Drawing;

namespace DataHiding
{
    class SteganographyHelper
    {
        enum State
        {
            hiding,
            filling_with_zeros
        };

        public static Bitmap MergeText(string text, Bitmap bmp)
        {
            State s = State.hiding;

            int charIndex = 0;
            int charValue = 0;
            long colorUnitIndex = 0;

            int zeros = 0;

            int R = 0, G = 0, B = 0;

            for (int i = 0; i < bmp.Height; i++)
            {
                for (int j = 0; j < bmp.Width; j++)
                {
                    Color pixel = bmp.GetPixel(j, i);

                    pixel = Color.FromArgb(pixel.R - pixel.R % 2,
                        pixel.G - pixel.G % 2, pixel.B - pixel.B % 2);

                    R = pixel.R; G = pixel.G; B = pixel.B;

                    for (int n = 0; n < 3; n++)
                    {
                        if (colorUnitIndex % 8 == 0)
                        {
                            if (zeros == 8)
                            {
                                if ((colorUnitIndex - 1) % 3 < 2)
                                {
                                    bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                                }

                                return bmp;
                            }

                            if (charIndex >= text.Length)
                            {
                                s = State.filling_with_zeros;
                            }
                            else
                            {
                                charValue = text[charIndex++];
                            }
                        }

                        switch (colorUnitIndex % 3)
                        {
                            case 0:
                                {
                                    if (s == State.hiding)
                                    {
                                        R += charValue % 2;

                                        charValue /= 2;
                                    }
                                } break;
                            case 1:
                                {
                                    if (s == State.hiding)
                                    {
                                        G += charValue % 2;

                                        charValue /= 2;
                                    }
                                } break;
                            case 2:
                                {
                                    if (s == State.hiding)
                                    {
                                        B += charValue % 2;

                                        charValue /= 2;
                                    }

                                    bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                                } break;
                        }
                           
                        colorUnitIndex++;

                        if (s == State.filling_with_zeros)
                        {
                            zeros++;
                        }
                    }
                }
            }

            return bmp;
        }

        public static string ExtractText(Bitmap bmp)
        {
            int colorUnitIndex = 0;
            int charValue = 0;

            string extractedText = String.Empty;

            for (int i = 0; i < bmp.Height; i++)
            {
                for (int j = 0; j < bmp.Width; j++)
                {
                    Color pixel = bmp.GetPixel(j, i);

                    for (int n = 0; n < 3; n++)
                    {
                        switch (colorUnitIndex % 3)
                        {
                            case 0:
                                {
                                    charValue = charValue * 2 + pixel.R % 2;
                                } break;
                            case 1:
                                {
                                    charValue = charValue * 2 + pixel.G % 2;
                                } break;
                            case 2:
                                {
                                    charValue = charValue * 2 + pixel.B % 2;
                                } break;
                        }

                        colorUnitIndex++;

                        if (colorUnitIndex % 8 == 0)
                        {
                            charValue = reverseBits(charValue);

                            if (charValue == 0)
                            {
                                return extractedText;
                            }

                            char c = (char)charValue;

                            extractedText += c.ToString();
                        }
                    }
                }
            }

            return extractedText;
        }

        public static int reverseBits(int n)
        {
            int result = 0;

            for (int i = 0; i < 8; i++)
            {
                result = result * 2 + n % 2;

                n /= 2;
            }

            return result;
        }
    }
}


How To Use :

Following Tools will work by the following steps

Step 1: Load the image 



Step 2 : Load the File or Manually type the information





Step 3: Give the Password 
Step 4:Save the information into another file




Now you can send this file or post in facebook all of them see only the image ,then you end user download the File and see the information by the following steps.

Step 1: Load the image which is download 
Step 2: Type the password which is provide to hide the information
Step 3: Click Extract button, to see the information.



From this article you can learn how to hide the information behind the images and make explicitly visible some thing for others.


4 comments:

  1. Above code is complete source code for build this exe

    ReplyDelete
  2. Thank you so much but i cannot find this function RijndaelAlgo.Decrypt and also RijndaelAlgo.Encrypt. i am getting error.

    ReplyDelete
  3. http://dotnetvisio.blogspot.in/2013/11/rijndael-symmetric-algorithm-encryption.html

    Above link have the implementation of rijndael algorithm, you have to change the key if you need

    ReplyDelete
  4. Plz upload the designer file too.

    ReplyDelete