Professional Documents
Culture Documents
Submitted By:
Rohit Jaiswal
CSE – 06000025
SUPERVISOR:
Rajeev Srivastava
Reader
Computer Science and Engineering
CERTIFICATE
This is to certify that Rohit Jaiswal ( Roll no. 06000025), student of the
Department of Computer Science & Engineering , Institute of
Technology, Banaras Hindu University, Varanasi worked for his
B.Tech. Minor Project entitled “Image and Audio Steganography”
under my supervision from beginning of fourth semester of B.Tech.
program 2006-2010.
(Rajeev Srivastava)
Reader
Department of Computer Science & Engineering
Institute Of Technology
Banaras Hindu University
Page | 2
ACKNOWLEDGEMENT
It has indeed been a great privilege for me to have Mr. Rajeev Srivastava,
Department of Computer Science and Engineering, Institute of Technology,
Banaras Hindu University, as my mentor for this project. His awe-inspiring
personality, superb guidance and constant encouragement are the motive force
behind this project work. I take this opportunity to express my utmost gratitude to
him. I am also indebted to him for his timely and valuable advice.
( Rohit Jaiswal )
Roll No. : 06000025
B.Tech (Part II) Semester IV
Department of Computer Science & Engineering
Institute Of Technology ,Banaras Hindu University
Page | 3
Contents
1. Abstract ...........................................................................................................5
2. Chapter 1: Introduction.....................................................................................6
Steganography and Cryptography……………………………………...6
Scope of Steganography………………………………………………...7
6. Chapter 5. Algorithms………………………………………………………………17
8. References......................................................................................................35
9. Appendix…………………………......................................................................36
Keywords……………...……………………………………………………….36
Source Code............................................................................................37
Page | 4
ABSTRACT
Steganography is the art and science of writing hidden messages in such
a way that no one apart from the sender and intended recipient even
realizes there is a hidden message.
There are often cases when it is not possible to send messages openly or in
encrypted form. This is where steganography can come into play. While
cryptography provides privacy, steganography is intended to provide secrecy.
This project deals with hiding of text behind multimedia, i.e. digital images,
wave audio, real media audio, etc. Cryptographic cipher is used before hiding text
to make this procedure more secure. The GUI has been given a funky look by
using flash.
IMPORTANT KEYWORDS
Page | 5
CHAPTER 1
Introduction
The word steganography is of Greek origin and means "covered, or hidden
writing". Steganography is the art and science of communicating in a way which
hides the existence of the communication. By contrast, cryptography obscures the
meaning of a message, but it does not conceal the fact that there is a message.
The message above is a sentence in English that is encrypted using Pretty Good Privacy (PGP),
probably the most commonly used e-mail encryption software today.
Page | 6
SCOPE OF STEGANOGRAPHY
Steganography is a very interesting and advantageous science these days and has
following uses:
Digital Watermarking
To protect a copyright on information. Photo collections, sold on CD,
often have hidden messages in the photos which allow detection of
unauthorized use. The same technique applied to DVDs is even more
effective, since the industry builds DVD recorders to detect and disallow
copying of protected DVDs.
The simplest and oldest are used in map making, where cartographers
sometimes add a tiny fictional street to their maps, allowing them to
prosecute copycats.
Page | 7
CHAPTER 2
TECHNOLOGIES USED
.SWF file
.EXE file ( built in Flash)
( built in C#)
Functions
( built in C#)
Page | 8
CHAPTER 3
THEORETICAL BACKGROUND
ANALYSIS OF DIGITAL IMAGE
A 24-bit color scheme, as the term suggests, uses 24 bits per pixel and
provides a much better set of colors. In this case, each pixel is represented by three
bytes, each byte representing the intensity of the three primary colors red, green,
and blue (RGB), respectively. The color orange, for example, would be displayed
with red set to 100% , green set to 50% and no blue .
The size of an image file, then, is directly related to the number of pixels
and the granularity of the color definition. A typical 640x480 pix image using a
palette of 256 colors would require a file about 307 KB in size (640 • 480 bytes),
whereas a 1024x768 pix high-resolution 24-bit color image would result in a 2.36
MB file (1024 • 768 • 3 bytes).
GIF and 8-bit BMP files employ what is known as lossless compression, a
scheme that allows the software to exactly reconstruct the original image. JPEG,
on the other hand, uses lossy compression, which means that the expanded image
Page | 9
is very nearly the same as the original but not an exact duplicate. Lossless
compression is much better suited to applications where the integrity of the
original information must be maintained, such as steganography. While JPEG can
be used for stego applications, it is more common to embed data in GIF or BMP
files.
The simplest approach to hiding data within an image file is called Least
Significant Bit (LSB) insertion. In this method, we can take the binary
representation of the hidden_data and overwrite the LSB of each byte within the
cover_image. If we are using 24-bit color, the amount of change will be minimal
and indiscernible to the human eye. As an example, suppose that we have three
adjacent pixels (nine bytes) with the following RGB encoding:
10010101 00001101 11001001
10010110 00001111 11001010
10011111 00010000 11001011
Now suppose we want to "hide" the following 9 bits of data (the hidden data
is usually compressed prior to being hidden): 101101101. If we overlay these 9 bits
over the LSB of the 9 bytes above, we get the following (where bits in bold have
been changed):
10010101 00001100 11001001
10010111 00001110 11001011
10011111 00010000 11001011
Note that we have successfully hidden 9 bits but at a cost of only changing
4, or roughly 50%, of the LSBs.
A 640x480 pixel image, the size of a small computer monitor, can hold over
400,000 characters. That's a whole novel hidden in one modest photo! This poject
involves following formats of images:
Page | 10
BMP Image File Format
File Header
Data Size(Bytes)
File Type(BM in case of BMP files) 2
File Size 4
Reserved Byte(Always 0) 1
Reserved Byte(Always 0) 1
Bf of Bits
Size of Info Header 4
Width of Bitmap 2
Height of Bitmap 2
No of planes(1 for BMP) 1
Bit Count(Bits/Pixel, Must be 1, 4, 8, 24) 1
Type of Compression used(none) 2
Size of Image Data in Bytes 2
Horizontal Resolution in Pixels/Meter 2
Vertical Resolution in Pixels/Meter 2
No of Color’s Indexes Used 2
Important Color Indexes 2
Data Size(Bytes)
R(Red) 1
B(Blue) 1
G(Green) 1
Reserved Word for RGB 1
Page | 11
ANALYSIS OF DIGITAL AUDIO
The key innovation in recent years was to choose an innocent looking cover
that contains plenty of random information, called white noise. You can hear white
noise as a the nearly silent hiss of a blank tape playing. The secret message
replaces the white noise, and if done properly it will appear to be as random as the
noise was. Thus the basic design principle of steganographic systems is
“replacing high entropy noise with a high entropy secret transmission” .
Page | 12
Wave File Format
Wave Header
Data Size(Bytes)
Header Name(RIFF) 4
File Size 4
Format Name(wave) 4
Key Word(fmt) 4
Channels(Mono = 1, Stereo = 2) 1
Frequency 4
Blank(Less Important Data) 6
Bit Resolution 1
Blank(Less Important Data) 12
Wave Data
Data Size(Bytes)
Sound Length 1
Frequency 1
Sample Data Rest Of Wave File
Page | 13
CHAPTER 4
CONTEXT DIAGRAM
PLAIN TEXT OR
COVER MEDIUM TEXT FILE STEGNO KEY
(Image or Audio File) (Text to be Hidden)
STEGNO-ENCODING
TOOL
STEGNO
MEDIUM
STEGNO-DECODING
TOOL
.DAT FILE
CONTAINING
HIDDEN TEXT
Page | 14
DATA FLOW DIAGRAM
ENCODING
STEGNO
PLAIN KEY
TEXT
Vigenere
Cipher
Arithmetic
Encripted coding
Text
Conversion
into ASCII
form Key
Conversion Information
into 8-bit
form
Bit
Stream
STEGNO
MEDIUM
Page | 15
DECODING
Arithmetic
STEGNO coding Key
KEY Information
Bit Stream of
Hidden Text
Conversion
into 8-bit
form Conversion
into ASCII
form
Vigenere Encripted
Cipher Text
ORIGINAL
TEXT
Page | 16
CHAPTER 5
ALGORITHMS
ENCODING
Least significant bit (LSB) coding is the simplest way to embed information in a
digital Image or Audio file. By substituting the least significant bit of each
sampling point in Audio and each pixel in Image with a binary message, LSB
coding allows for a large amount of data to be encoded.
In LSB coding, the ideal data transmission rate is 1 kbps per 1 kHZ.
Page | 17
ALGORITHM FOR ENCODING
If (Bit_stream[i]==1)
audio_stream[i]=audio_stream[i] OR “00000001”;
Page | 19
ALGORITHM FOR DECODING
char C;
If (i%3==1) C=R;
If (i%3==1) C=G;
If (i%3==1) C=B;
Page | 20
STEP 3. for(int i=1;i<8n;i++)
{
Bit_stream[i]=least significant digit of audio_stream[i];
}
string ciphertext ;
convert Bit_stream ASCII form;
convert ASCII form ciphertext;
//apply dencription algorithm on this string
string plaintext = inverse_Vigenere_cipher(ciphertext);
PRINT plaintext;
Page | 21
Vigenere Cipher
The person sending the message chooses a keyword and repeats it until it matches
the length of the plaintext, for example, the keyword "LEMON" makes :
Key: LEMONLEMONLE
Page | 22
CHAPTER 6
IMPLEMENTATION
FUNCTIONS
Page | 23
FUNCTION MAP
axShockwav
eFlash1_FS
EXE file Command()
(built in
CLASS
Stegnos text_
SWF file decrypt()
(built in Flash)
gen_binary_ get_key()
code()
text_
encrypt()
CLASS
CLASS Stack
ENCODE
CLASS
DECODE
encrypt()
decrypt()
Page | 24
CHAPTER 7
ENCODING
Page | 25
Page | 26
Page | 27
Page | 28
Page | 29
DECODING
Page | 30
Page | 31
Page | 32
CHAPTER 8
This project deals with Steganography in Image and Audio files using
Least Significant Bit (LSB) coding. This project can uplifted by
considering following measures:
Page | 33
REFERENCES
Page | 34
APPENDIX
Page | 35
SOURCE CODE
PROGRAM.CS
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Steganography
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Stegnos());
}
}
}
FORM1.CS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Steganography
{
public partial class Stegnos : Form
{
public Stegnos()
{
InitializeComponent();
this.axShockwaveFlash1.FSCommand += new
AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEventHandler(axShockw
aveFlash1_FSCommand);
}
string code_text;
string myTextFile = "", myPassword = "", myText = "";
public string myImageFile = "";
int index=0;
string mybinarycode_final = "",myAudioFile="";
string final_text = "";
Page | 36
string sampleStr = "";
Stream outputstream;
int chkval = 0;
if (e.command == "exit")
Application.Exit();
if (e.command == "password")
{
myPassword = e.args.ToString();
}
if (e.command == "savetextfile")
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "Binary Files (*.dat)|*.dat";
if (dlg.ShowDialog() == DialogResult.OK)
{
StreamWriter fwriter = File.CreateText(dlg.FileName);
fwriter.WriteLine(final_text);
fwriter.Close();
}
}
if(e.command == "savedfile")
{
SaveFileDialog dlg = new SaveFileDialog();
Page | 37
BinaryWriter messageWriter = new BinaryWriter(new
MemoryStream());
FileStream fs = new FileStream(myAudioFile,
FileMode.Open);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
messageWriter.Write(buffer);
messageWriter.Seek(0, SeekOrigin.Begin);
Stream WaveStream = messageWriter.BaseStream;
WaveStream.Read(ch, 0, 100);
writer.Write(ch);
generate_bincodes();
char[] message = mybinarycode_final.ToCharArray();
int count = 0;
int messagecount = 0;
//int streamcount = 44;
for(int i=0;i<6;i++)
{
WaveStream.Read(ch, 0, 1);
writer.Write((byte)(msglnth % 10));
msglnth = msglnth / 10;
}
Page | 38
Application.Exit();
}
while (messagecount < messageLength)
{
sampleint = WaveStream.ReadByte();
if (count % advancesteps == 0)
{
if (message[messagecount] == '1')
{
if (sampleint % 2 == 0 && sampleint < 255)
{
sampleint++;
}
else
sampleint = 255;
}
else if (messagecount < messageLength)
{
if (sampleint % 2 == 1 && sampleint < 255)
{
sampleint++;
}
else
sampleint = 254;
}
messagecount++;
}
count++;
writer.Write((byte)sampleint);
}
}
writer.Close();
}
if (chkval != 1)
{
Image img = new Bitmap(pictureBox1.Image);
this.SuspendLayout();
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
this.ResumeLayout();
img.Save(dlg.FileName, format);
}
}
Page | 39
}
if (e.command == "decodeaudiofile")
{
BinaryWriter messageWriter = new BinaryWriter(new
MemoryStream());
FileStream fs = new FileStream(e.args, FileMode.Open);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
messageWriter.Write(buffer);
messageWriter.Seek(0, SeekOrigin.Begin);
Stream WaveStream = messageWriter.BaseStream;
int count = 0;
int messagecount = 0;
float keygen = get_key(myPassword);
int advancesteps = (int)(keygen * 100);
if (advancesteps < 50)
advancesteps = 50;
int msglnth=0;
int pow=1;
for (int i = 0; i < 6; i++)
{
Page | 40
char[] binvalue = { '0', '0', '0', '0', '0', '0', '0', '0'
};
for (int j = 0; j <= 7; j++)
binvalue[j] = original_val[i + j];
final_text = text_decrypt(coded_text.Length,
myPassword.Length, coded_text.ToCharArray(), myPassword.ToCharArray());
}
if (e.command == "textfile")
{
myTextFile = e.args.ToString();
BinaryWriter messageWriter = new BinaryWriter(new
MemoryStream());
FileStream fs = new FileStream(e.args, FileMode.Open);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
messageWriter.Write(buffer);
messageWriter.Seek(0, SeekOrigin.Begin);
}
if (e.command == "decodeimagefile")
{
Page | 41
int codex = (int)((key * 1000000)%1000);
int codey = (int)(key * 1000);
if(codex == 0)
codex = 2;
if(codey == 0)
codey = 4;
final_text = text_decrypt(coded_text.Length,
myPassword.Length, coded_text.ToCharArray(), myPassword.ToCharArray());
Page | 42
}
if (e.command == "text")
{
myText = e.args.ToString();
int length_text = myText.Length;
int length_key = myPassword.Length;
char[] textline = myText.ToCharArray();
char[] passwd = myPassword.ToCharArray();
text_encrypt(length_text, length_key, textline, passwd);
}
if(e.command == "audiofile")
{
myAudioFile = e.args;
}
if (e.command == "imagefile")
{
myImageFile = e.args.ToString();
try
{
pictureBox1.Image = new Bitmap(myImageFile);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Page | 43
Color pixelcolor;
pixelcolor = bitmap.GetPixel(codex, codey);
pixelcolor = Color.FromArgb(red, green, blue);
length = code_text.Length * 8;
generate_bincodes();
if(codex == 0)
codex = 2;
if(codey == 0)
codey = 4;
bitmap.SetPixel(codex, codey, pixelcolor);
}
}
Page | 44
if(count<8)
for(int y=count;y<8;y++)
s.push(0);
mybinarycode_final += s.display();
i++;
j++;
}
Page | 45
private float get_key(string pwd)
{
int k = 0, i = 0, j = 0;
float[] prob ={ 0.08f, 0.02f, 0.03f, 0.03f, 0.12f, 0.02f, 0.02f,
0.05f, 0.08f, 0.01f, 0.01f, 0.04f, 0.03f, 0.07f, 0.08f, 0.02f, 0.01f, 0.06f,
0.06f, 0.06f, 0.03f, 0.01f, 0.02f, 0.01f, 0.02f, 0.01f };
float[] range_to ={ 0.08f, 0.1f, 0.13f, 0.16f, 0.28f, 0.30f,
0.32f, 0.37f, 0.45f, 0.46f, 0.47f, 0.51f, 0.54f, 0.61f, 0.69f, 0.71f, 0.72f,
0.78f, 0.84f, 0.9f, 0.93f, 0.94f, 0.96f, 0.97f, 0.99f, 1.00f };
float[] range_from ={ 0.00f, 0.08f, 0.1f, 0.13f, 0.16f, 0.28f,
0.30f, 0.32f, 0.37f, 0.45f, 0.46f, 0.47f, 0.51f, 0.54f, 0.61f, 0.69f, 0.71f,
0.72f, 0.78f, 0.84f, 0.90f, 0.93f, 0.94f, 0.96f, 0.97f, 0.99f };
float low = 0.00f, high = 1.00f, diff = 1.00f;
int x = 0;
char[] mypassword = pwd.ToCharArray();
int pwdlength = pwd.Length;
while (k < pwdlength)
{
if (((int)mypassword[k] >= 97) && ((int)mypassword[k] <= 122))
x = (int)mypassword[k] - 97;
else if (((int)mypassword[k] >= 65) && ((int)mypassword[k] <=
90))
x = (int)mypassword[k] - 65;
diff = high - low;
high = low + diff * range_to[x];
low = low + diff * range_from[x];
k++;
}
return (low);
}
}
}
ENCODE.CS
Page | 46
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace Steganography
{
class encode:Stegnos
{
public Bitmap encrypt(int x, int y, int length, char[] text,Bitmap
bitmap)
{
}
}
transformmatrix[x, y] = 3;
int row = 0, col = 0, xprob = 0, yprob = 0, xadd = 0, yadd = 0;
row = bitmap.Height;
col = bitmap.Width;
xprob = x;
yprob = y;
if (yprob % 2 == 1)
yadd = yprob - 1;
else
yadd = yprob;
if (xprob % 2 == 1)
xadd = xprob - 1;
else
xadd = xprob;
if (row % 2 == 0)
row--;
if (col % 2 == 0)
col--;
Page | 47
if (xadd == 0)
xadd = 2;
if (yadd == 0)
yadd = 4;
int flag = 0;
if (text[i] == '0')
{
transformmatrix[x, y] = 2;
rotatematrix[x, y] = flag % 3;
break;
case 2:
Page | 48
if (green == 0)
{
green = 2;
}
else if (green % 2 == 1)
{
if (green == 255)
green--;
else
green++;
}
break;
case 0:
if (blue == 0)
{
blue = 2;
}
else if (blue % 2 == 1)
{
if (blue == 255)
blue--;
else
blue++;
}
break;
}
}
else if (text[i] == '1')
{
transformmatrix[x, y] = 1;
rotatematrix[x, y] = flag % 3;
Page | 49
break;
case 2: if (green % 2 == 0)
{
if (green == 0)
green++;
else
green--;
pixelcolor = Color.FromArgb(red, green, blue);
bitmap.SetPixel(x, y, pixelcolor);
break;
case 0: if (blue % 2 == 0)
{
if (blue == 0)
blue++;
else
blue--;
pixelcolor = Color.FromArgb(red, green, blue);
bitmap.SetPixel(x, y, pixelcolor);
break;
}
}
}
return (bitmap);
}
}
}
DECODE.CS
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
Page | 50
using System.Windows.Forms;
namespace Steganography
{
class decode:Stegnos
{
public string decrypt(int x,int y,Bitmap bitmap)
{
row = bitmap.Height;
col = bitmap.Width;
xprob = x;
yprob = y;
if (yprob % 2 == 1)
yadd = yprob - 1;
else
yadd = yprob;
if (xprob % 2 == 1)
xadd = xprob - 1;
else
xadd = xprob;
if (row % 2 == 0)
row--;
if (col % 2 == 0)
col--;
if (xadd == 0)
xadd = 2;
if (yadd == 0)
yadd = 4;
int k = 0;
Page | 51
k++;
x += xadd;
while (x >= col)
x -= col;
y += yadd;
while (y >= row)
y -= row;
if (red % 2 == 0)
outputstring[i] = '0';
else
outputstring[i] = '1';
red = 0;
pixelcolor = Color.FromArgb(red, green, blue);
bitmap.SetPixel(x, y, pixelcolor);
break;
case 2: if (green == 0)
{
y++;
if (y >= row)
y = 0;
}
if (green % 2 == 0)
outputstring[i] = '0';
else
outputstring[i] = '1';
green = 0;
pixelcolor = Color.FromArgb(red, green, blue);
bitmap.SetPixel(x, y, pixelcolor);
break;
case 0: if (blue == 0)
{
y++;
if (y >= row)
y = 0;
}
if (blue % 2 == 0)
outputstring[i] = '0';
Page | 52
else
outputstring[i] = '1';
blue = 0;
pixelcolor = Color.FromArgb(red, green, blue);
bitmap.SetPixel(x, y, pixelcolor);
break;
}
}
for (int i = 0; i < textlength; i++)
{
final += outputstring[i].ToString();
}
return (final);
}
}
}
Page | 53