Sunteți pe pagina 1din 130

Project Report On Steganography

Submitted for partial fulfillment of the award of

BACHELOR OF TECHNOLOGY
DEGREE Session 2009-10 In

COMPUTER SCIENCE & ENGINEERING


By

SACHIN KR. RATHI(Project Lead) (0622510046) PRADEEP KUMAR MAURYA (0622510035) KAMLESH KUMAR MADDHESHIYA (0622510023) KRISHN KANHAIYA AGRAWAL (0622510027)

Under the guidance of

Mr. Murari Kumar Singh ACCURATE INSTITUTE OF MANAGEMENT & TECHNOLOGY, GREATER NOIDA May, 2010

AFFILIATED TO UTTAR PRADESH TECHNICAL UNIVERSITY, LUCKNOW

Certificate

Certified that Sachin Kumar Rathi, Pradeep Kumar Maurya, Kamlesh Kumar Maddheshiya and Krishn Kanhaiya Agrawal has carried out the Project work presented in this project entitled Steganography for the award of Bachelor of Technology from Uttar Pradesh Technical University, Lucknow under my supervision. The Project embodies result of original work and studies carried out by Student himself and the contents of the Project do not form the basis for the award of any other degree to the candidate or to anybody else.

Date: Abhishek Singhal

Mr.

HOD

Acknowledgement
7

Apart from the efforts of me, the success of this project depends largely on the encouragement and guidelines of many others. I take this opportunity to express my gratitude to the people who have been instrumental in the successful completion of this project.

I would like to show my greatest appreciation to Mr. Murari Kumar Singh. I cant say thank you enough for his tremendous support and help. I feel motivated and encouraged every time I attend his meeting. Without his encouragement and guidance this project would not have materialized.

The guidance and support received from all the team members including Sachin Kumar Rathi, Pradeep Kumar Maurya, Kamlesh Kumar Maddheshiya and Krishan Kanhaiya Agrawal who contributed and are contributing to this project, was vital for the success of the project. I am grateful for their constant support and help.

ABSTRACT
8

The project aims to find out the vulnerability in the existing system. Vulnerability counts for the place in the medium where by applying steganography techniques data can be concealed safely without affecting the quality of the medium. Steganography is the data security implementation technique that is much reliable than have selected for implementing this technique are text, file and image.
The project provides various utilities to enhance the ease to the user to select an appropriate cryptographic algorithm to prevent the leakage of data if gone through steganography. Steganography topic means security at each and every level. Finally an attempt would be made to enhance software performance and user friendliness so to make it easy to operate.

TABLE OF CONTENT

TITLE

PAGE NO.

Certificate 2 Acknowledge Abstract List of tables List of figures 6 6 3 4

1. Introduction 1.1 1.2 1.3 Introduction of project Steganographic system Objective 7 8 9 9 10 10 11 11 13

1.4 Scope 2. System Analysis 2.1 Problem Definition 2.2 2.3 2.4 2.5 Existing System Proposed System LSB Based Steganography Technique Functions to be provided

3. Feasibility Analysis 3.1 14 3.1.1 3.1.2 3.1.3 3.1.4 Technical Feasibility Behavioural Feasibility Economical Feasibility Operational Feasibility 14 15 15 16 Feasibility Study

4. System Requirement Specification 4.1 System Design 4.2 Detailed Design 4.3 Work breakdown structure 4.4 Use case diagram 4.5 Data flow diagrams

17 17 18 19 20
10

4.6

Processing Environment 4.6.1 Software Requirements 4.6.2 Hardware Requirements

26 26 26 27 118 120 121 122 122 123 124 128


129

5. Coding 6. Testing 7. Project Plan 5.1 Team Structure 5.2 Development Schedule 8. System Features and Limitations 6.1 Features 6.2 Limitations 6.3 Applications 7. Snapshots 8. Conclusion 9. REFERENCES List of Tables
Table No. Table 2.1 Example of LSB Technique Table 121 5.2 Development

Page No. 12 Schedule

List of Figures

Fig. No.

Page No.

Fig 1.1 Steganographic System Fig 1.2 Example of Secret Key Steganography
Fig 4.1 Work breakdown structure 18 Fig 4.2 Use case diagram Fig 4.3 Level-0 DFD Fig 4.4 Level-1 DFD Fig 4.5 Level-2 DFD (Steganography Encryption & Decryption process on secret message) 22 Fig 4.6 Level-2 DFD (Steganography Encryption & Decryption 23 Fig 4.7 Level-2 DFD (Steganography process with process on secret file)

8 9

19 20 21

11

compression & decompression on secret message) Fig 4.8 Level-2 DFD (Steganography process with compression & decompression on secret file) 25 Fig 7.1 Main Form Fig 7.2 Encrypt Form GUI Fig 7.3 Password Validation 126 Fig 7.4 Encrypted Message 127 124 125 24

12

Chapter 1 INTRODUCTION 1.1 Introduction of project


Steganography is a technology that hides a message within a text, file or a picture. It is often confused with cryptography, not in name but in appearance and usage. Cryptography was created as a technique for securing the secrecy of communication and many different methods have been developed to encrypt and decrypt data in order to keep the message secret. Unfortunately it is sometimes not enough to keep the contents of a message secret, it may also be necessary to keep the existence of the message secret. The technique used to implement this, is called Steganography. In Histories the Greek historian Herodotus writes of a nobleman, Histaeus, who needed to communicate with his son-in-law in Greece. He shaved the head of one of his most trusted slaves and tattooed the message onto the slaves scalp. When the slaves hair grew back the slave was dispatched with the hidden message. In the Second World War the Microdot technique was developed by the Germans. Information, especially photographs, was reduced in size until it was the size of a typed period. Extremely difficult to detect, a normal cover message was sent over an insecure channel with one of the periods on the paper containing hidden information. Today steganography is mostly used on computers with digital data being the carriers and networks being the high speed delivery channels. Throughout history, a multitude of methods and variations have been used to hide information. David Kahn's The Code breaker provides an excellent accounting of this history. Bruce Norman recounts numerous tales of cryptography and steganography during times of war in Secret Warfare: The Battle of Codes and Ciphers. The word steganography is of Greek origin and means "concealed writing". The word steganography is derived from the Greek words stegos meaning cover and grafie meaning writing Greek Words: STEGANOS Covered GRAPHIE Writing
13

Steganography is the art and science of writing hidden messages. So, that only intended recipient knows the existence of the message.

Steganographic formula:
The following formula provides a very generic description of the pieces of the steganographic process: cover_medium + hidden_data + stego_key = stego_medium (1.1)

In this context, the cover_medium is the file in which we will hide the hidden_data, which may also be encrypted using the stego_key (Steganography tool). The resultant file is the stego_medium (which will, of course be the same type of file as the cover_medium). The most common stego method is the LSB approach, or least significant bit in which we Substitute the least significant bit of each sampling point with a binary message.

1.2

Steganographic System

Fig 1.1 Steganographic System

14

Fig 1.2 Example of Secret Key Steganography The left image (8.9K) contains no hidden data. The right one (11.2K) contains about 5K of password-protected text.

1.3 Objective In our project of steganography our basic objective is to hide the information in such a manner that even its presence cannot be detected. Almost every organization be it industrial or educational are constantly making an effort to build an unbreakable security system to protect confidential data from the intruders. Here actually where it comes to the need of steganography. The main goal of STEGANOGRAPHY in text, image and files is to equip the users with easy access to the various activities of hiding confidential data or information (whether a text, image or a file) in the form of the features provided in the project. Your data is encrypted with a password using Steganograhy algorithms (for additional protection) and hidden in the carrier medium.

1.4 Scope The scope of the project extends to develop software that is intended to implement various techniques of Steganography using various algorithms. This software can further be extended to be used with other cryptosystems. The techniques used make it impossible to detect that there is anything inside in the carrier file, but the intended recipient can obtain the hidden data.

Chapter 2
15

System Analysis

2.1 Problem Definition


People not only want their messages to be encrypted but they want to hide the existence of such information. Any good cryptologist could find whether information is hidden in a file or not. Since we dont want such persons to learn our information, we need some system such that even when the information is revealed, it should be of no use. People need high security and user friendly environment .Thats why we need steganography. The difference between steganography and other software is that in steganography one even doesnt realize that some information is present in given medium, while other softwares suffer from this drawback. Also there are cases where we do need security but not as so high level that is where establishing a firewall or any other software may not be the feasible solution. Time efficiency also plays a major role in the choice of hiding data. How much time we require to create that message and how much time we require to encrypt and decrypt that message should also be consider .So we need to overcome these problems by developing such a security software which need minimum system requirements as well it should be cost effective and user friendly at the same time.

2.2 Existing System


Steganography is an evolving branch of cryptography. People not only want their messages to be encrypted but they want to hide the existence of such information. A variety of systems are providing this facility of hiding information. But, nobody can deny the fact that with a lot of hard work and sincere effort any good cryptologist could find whether information is hidden in a file or not. Since we dont want such persons to learn our information, we need some system such that even when the information is revealed, it should be of no use.
16

2.3 Proposed System


This project was specifically for programmers that are interested in art of hiding secret information. The application is primarily intended to be used to inconspicuously hide confidential and proprietary information by anyone seeking to hide information. This software has an advantage over other information security systems because hidden text is in the form of images, which are not obvious text information carriers. Because of its user-friendly interface, the application can also be used by anyone who wants to securely transmit private information. The main advantage of this program for individuals is that they do not have to have any knowledge about stegnography or encryption. The visual way to encode the text, image for average users to navigate within the program. In the business world steganography can be used to hide a secret chemical formula or plans for a new invention. Steganography can also be used for corporate espionage by sending out trade secrets without anyone at the company being any the wiser. Steganography can also be used in the non-commercial sector to hide information that someone wants to keep private. This project is feasible for several reasons.

2.4

LSB Based Steganography Technique


Least significant bit (LSB) coding is the simplest way to embed information in a digital

file. By substituting the least significant bit of each sampling point 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. In this technique LSB of binary sequence of each sample of digitized audio file is replaced with binary equivalent of secret message. In some implementations of LSB coding, however, the two least significant bits of a sample are replaced with two message bits to four bits. This increases the amount of data that can
17

be encoded but also increases the amount of resulting noise in the file as well. Thus, one should consider the signal content before deciding on the LSB operation to use.

For example: If we want to hide the letter A (binary equivalent 01100101) to an digitized audio file where each sample is represented with 16 bits, then LSB of 8 consecutive samples (each of 16 bit size) is replaced with each bit of binary equivalent of the letter A.

Table 2.1 Example of LSB Technique

16 bit message 1001 1000 0011 1100 1101 1011 0011 1000 1011 1100 0011 1101 1011 1111 0011 1100 1011 1010 0111 1111 1111 1000 0011 1100 1101 1100 0111 1000

A in binary 0 1 1 0 0 1 0

16 bit encoded message 1001 1000 0011 1100 1101 1011 0011 1001 1011 1100 0011 1101 1011 1111 0011 1100 1011 1010 0111 1110 1111 1000 0011 1101 1101 1100 0111 1000

2.5 Functions to be provided


Embed message into a file.

18

Embed file (image, text, pdf etc.) into other file. Retrieve message from the file containing embedded message. Retrieve file from file containing embedded message. Encrypting message/message file before embedding into other files.

Chapter 3 Feasibility Analysis


19

3.1 Feasibility Study


Feasibility study is about the viability of a system. It helps in taking decisions such as which software to use, hardware combinations, etc. It provides: Fast retrieval of data. Data security. Efficient way to embed data. Better accuracy.

Four Phases of Feasibility Study:

3.1.1 Technical Feasibility


Technical Feasibility is concerned with the available hardware and the software resources whether they meet the given requirement of the analyzed system or not which include latest machinery and the techniques are required handling the system. It is the process of assessing the development organization's ability to construct a proposed system. Our proposed system is technically feasible because:

The H/W and S/W required are easy to install and handle. The necessary H/W configuration and software platform is already there. The system supports interactivity with the user through GUI.

3.1.2 Behavioural Feasibility


20

Behavioral feasibility determines how much effort will go in the proposed information system, and in educating and training the employees on the new system, along with the new ways of conducting the business. Behavioral study strives on ensuring that the equilibrium of the organization and status quo in the organization neither are nor disturbed and changes are readily accepted by the users. The proposed system is behaviorally feasible because of the following: It has user-friendly interface. It is reliable. It requires no efforts for training the software.

3.1.3 Economic Feasibility


It is a process of identifying the financial benefits and costs associated with a development project. This project is found to be economically feasible since security is the need of the time. A cost-benefit analysis is made considering the intricacies such as development cost, time to implementation, support costs, business process effectiveness, and maintainable design. Once the required hardware and software requirement get fulfilled, there is no need for the user of our system to spend for any additional overhead. For the user, the system will be economically feasible in the following aspect: This application can also be used by anyone who wants to securely transmit private information. Cost of implementation User friendliness of software There will be no training cost as system has very user friendly GUI. Our system will reduce time that is wasted in manual processes.

21

3.1.4 Operational feasibility:


It is the process of assessing the degree to which a proposed system solves business problems or takes advantage of business opportunities the questions that are assessed are:

Will the solution fulfill the users requirements? To what degree? How will the solution change the users Work environment? How do users feel about such a solution?

The feedbacks for these questions are reviewed and the system proposed is found to be feasible.

Chapter 4
22

System Requirement Specification 4.1 System Design


The design phase is considered as most constructive and innovative phase in the whole cycle of system development. The phase is resolved for building a Work breakdown structure (WBS) that gives an exact path to reach the objective. This path is paved with the prior knowledge which has been gathered from the analysis and feasibility phase. With the knowledge of all the working of the organization it will be much easier to route and plan without much affecting the core working of the organization. Thus the objective of the design phase is to take the SRS document as input and produce the different modules and design solutions.

4.2 Detailed Design


The detailed design basically comprises of the functionality of the system that how the system works. To demonstrate the functionality of the system, Use case diagrams may be used and for working flow of the system, data flow diagram may be used. The DFD is a simple graphical formalism that can be used to represent a system in terms of the input data to the system. Various processing carried out on these data and the output data generated by the system. It does not supply details description (how) of modules but (what) and (from where) and (to where) of each and every module of the system. Data flow diagrams of level 0, 1 and 2 have been shown too simply and break the problem into atomic state.

23

4.3 Work breakdown structure

Fig 4.1 Work breakdown structure

24

4.4 Use case diagram

Fig 4.2 Use case diagram

25

4.5 Data flow diagrams

Fig 4.3 Level-0 DFD

26

Fig 4.4 Level-1 DFD

27

Fig 4.5 Level-2 DFD (Steganography Encryption & Decryption process on secret message)

28

Fig 4.6 Level-2 DFD (Steganography Encryption & Decryption process on secret file)

29

Fig 4.7 Level-2 DFD (Steganography process with compression and decompression on secret message)

30

Fig 4.8 Level-2 DFD (Steganography process with compression and decompression on secret file)

31

4.6 Processing Environment

4.6.1 Software Requirements:

JDK 1.6: JDK is acronym for Java Development Kit, essentially a java platform, consisting of the API classes, a java compiler and the JVM interpreter. JDK is a software package that can be used to write, compile, debug and run java applications. JDK 1.6 has highly anticipated garbage collector, additional performance and security enhancements, 64-bit java plug in, windows2008 support.

4.6.2 Hardware Requirements:


Microprocessor: RAM: Disk Space: Monitor: Pentium III and further processor 32 MB and above Approx 4 MB Any monitor can solve the purpose

Operating system: Windows-98 and any higher version of Windows

32

Chapter 5 Coding
########### Steganography ############ import java.io.*; import java.nio.ByteBuffer; import java.util.zip.*; import javax.crypto.*; import javax.crypto.spec.*; import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*;

public class Steganography { public static final String VERSION= "2.0.0"; public static final byte[] VERSION_BYTE= {'2','0','0'}; public static final int OFFSET_JPG= 3; public static final int OFFSET_PNG= 42; public static final int OFFSET_GIF_BMP_TIF= 32; public static final short HEADER_LENGTH= 15* 4; public static final byte UUM= 0; public static final byte UUF= 1; public static final byte UEM= 2; public static final byte UEF= 3; public static final byte CUM= 4; public static final byte CUF= 5;
33

public static final byte CEM= 6; public static final byte CEF= 7;

private static Cipher cipher;

private static SecretKeySpec spec; private static String masterExtension, message;

private static File masterFile; private static byte features; private static int inputFileSize; private static int i, j, inputOutputMarker, messageSize, tempInt; private static short compressionRatio= 0, temp; private static byte byte1, byte2, byte3, byteArrayIn[]; private static ByteArrayOutputStream byteOut;

private Steganography() { System.out.println("Steganography" + " ready..."); }

public static String getMessage() { return message; }

34

public static boolean embedMessage(File masterFile, File outputFile, String msg, int compression, String password) { if(msg==null) { message= "Message is empty"; return false; } if(msg.length()<1) { message= "Message is empty"; return false; }

if(password!= null && password.length()<8) { message= "Password should be minimum of 8 Characters"; return false; }

messageSize= msg.length();

if(compression!= -1) { if(compression< 0) if(compression>9) compression= 0; compression= 9;

35

if(password== null) else } else { if(password== null) else }

features= CUM; features= CEM;

features= UUM; features= UEM;

try { byteOut= new ByteArrayOutputStream(); byte []messageArray= msg.getBytes(); messageSize= messageArray.length; inputFileSize= (int) masterFile.length();

byteArrayIn= new byte[inputFileSize];

DataInputStream in= new DataInputStream(new FileInputStream(masterFile)); in.read(byteArrayIn, 0, inputFileSize); in.close();

String fileName= masterFile.getName(); masterExtension= fileName.substring(fileName.length()-3, fileName.length());

if(masterExtension.equalsIgnoreCase("jpg"))
36

{ byteOut.write(byteArrayIn, 0, OFFSET_JPG); inputOutputMarker= OFFSET_JPG; } else if(masterExtension.equalsIgnoreCase("png")) { byteOut.write(byteArrayIn, 0, OFFSET_PNG); inputOutputMarker= OFFSET_PNG; } else { byteOut.write(byteArrayIn, 0, OFFSET_GIF_BMP_TIF); inputOutputMarker= OFFSET_GIF_BMP_TIF; }

byte tempByte[]= new byte[4]; for(i=24, j=0; i>=0; i-=8, j++) { tempInt= inputFileSize; tempInt>>= i; tempInt&= 0x000000FF; tempByte[j]= (byte) tempInt; } embedBytes(tempByte);

37

byteOut.write(byteArrayIn, inputOutputMarker, inputFileSizeinputOutputMarker); inputOutputMarker= inputFileSize;

writeBytes(VERSION_BYTE);

writeBytes(new byte[]{features});

if(features== CUM || features== CEM) { ByteArrayOutputStream arrayOutputStream= new ByteArrayOutputStream(); ZipOutputStream zOut= new ZipOutputStream(arrayOutputStream); ZipEntry entry= new ZipEntry("MESSAGE"); zOut.setLevel(compression); zOut.putNextEntry(entry);

zOut.write(messageArray, 0, messageSize); zOut.closeEntry(); zOut.finish(); zOut.close();

messageArray= arrayOutputStream.toByteArray(); compressionRatio= (short) ((double)messageArray.length / (double)messageSize * 100.0); messageSize= messageArray.length; }

38

writeBytes(new byte[]{(byte) compressionRatio});

if(features== UEM || features== CEM) { Cipher cipher= Cipher.getInstance("DES"); SecretKeySpec spec= new SecretKeySpec(password.substring(0, 8).getBytes(), "DES"); cipher.init(Cipher.ENCRYPT_MODE, spec); messageArray= cipher.doFinal(messageArray); messageSize= messageArray.length; }

tempByte= new byte[4]; for(i=24, j=0; i>=0; i-=8, j++) { tempInt= messageSize; tempInt>>= i; tempInt&= 0x000000FF; tempByte[j]= (byte) tempInt; } writeBytes(tempByte);

writeBytes(messageArray);

DataOutputStream out= new DataOutputStream(new FileOutputStream(outputFile)); byteOut.writeTo(out);


39

out.close(); } catch(EOFException e) { } catch(Exception e) { message= "Oops!!\nError: "+ e.toString(); e.printStackTrace(); return false; }

message= "Message embedded successfully in file '"+ outputFile.getName()+ "'."; return true; }

public static String retrieveMessage(SteganoInformation info, String password) { String messg= null; features= info.getFeatures();

try { masterFile= info.getFile(); byteArrayIn= new byte[(int) masterFile.length()];

40

DataInputStream in= new DataInputStream(new FileInputStream(masterFile)); in.read(byteArrayIn, 0, (int)masterFile.length()); in.close();

messageSize= info.getDataLength();

if(messageSize<=0) { message= "Unexpected size of message: 0."; return("#FAILED#"); }

byte[] messageArray= new byte[messageSize]; inputOutputMarker= info.getInputMarker(); readBytes(messageArray);

if(features== CEM || features== UEM) { password= password.substring(0, 8); byte passwordBytes[]= password.getBytes(); cipher= Cipher.getInstance("DES"); spec= new SecretKeySpec(passwordBytes, "DES"); cipher.init(Cipher.DECRYPT_MODE, spec); try { messageArray= cipher.doFinal(messageArray);
41

} catch(Exception bp) { message= "Incorrent Password"; bp.printStackTrace(); return "#FAILED#"; } messageSize= messageArray.length; }

if(features== CUM || features== CEM) { ByteArrayOutputStream by= new ByteArrayOutputStream(); DataOutputStream out= new DataOutputStream(by);

ZipInputStream zipIn= new ZipInputStream(new ByteArrayInputStream(messageArray)); zipIn.getNextEntry(); byteArrayIn= new byte[1024]; while((tempInt= zipIn.read(byteArrayIn, 0, 1024))!= -1) out.write(byteArrayIn, 0, tempInt);

zipIn.close(); out.close(); messageArray= by.toByteArray(); messageSize= messageArray.length; }


42

messg= new String(SteganoInformation.byteToCharArray(messageArray)); } catch(Exception e) { message= "Oops!!\n Error: "+ e; e.printStackTrace(); return("#FAILED#"); }

message= "Message size: "+ messageSize+ " B"; return messg; }

public static boolean embedFile(File masterFile, File outputFile, File dataFile, int compression, String password) { messageSize= (int) dataFile.length();

if(password!= null && password.length()<8) { message= "Password should be minimum of 8 Characters"; return false; }

if(compression!= 0) {
43

if(compression< 0) if(compression>9)

compression= 0; compression= 9;

if(password== null) else } else { if(password== null) else }

features= CUF; features= CEF;

features= UUF; features= UEF;

inputFileSize= (int) masterFile.length(); try { byteOut= new ByteArrayOutputStream();

byteArrayIn= new byte[inputFileSize];

DataInputStream in= new DataInputStream(new FileInputStream(masterFile)); in.read(byteArrayIn, 0, inputFileSize); in.close();

String fileName= masterFile.getName(); masterExtension= fileName.substring(fileName.length()-3, fileName.length());

44

if(masterExtension.equalsIgnoreCase("jpg")) { byteOut.write(byteArrayIn, 0, OFFSET_JPG); inputOutputMarker= OFFSET_JPG; } else if(masterExtension.equalsIgnoreCase("png")) { byteOut.write(byteArrayIn, 0, OFFSET_PNG); inputOutputMarker= OFFSET_PNG; } else { byteOut.write(byteArrayIn, 0, OFFSET_GIF_BMP_TIF); inputOutputMarker= OFFSET_GIF_BMP_TIF; }

byte tempByte[]= new byte[4]; for(i=24, j=0; i>=0; i-=8, j++) { tempInt= inputFileSize; tempInt>>= i; tempInt&= 0x000000FF; tempByte[j]= (byte) tempInt; } embedBytes(tempByte);
45

byteOut.write(byteArrayIn, inputOutputMarker, inputFileSizeinputOutputMarker); inputOutputMarker= inputFileSize;

writeBytes(VERSION_BYTE);

writeBytes(new byte[]{features});

byte []fileArray= new byte[messageSize]; in= new DataInputStream(new FileInputStream(dataFile)); in.read(fileArray, 0, messageSize); in.close();

if(features== CUF || features== CEF) { ByteArrayOutputStream arrayOutputStream= new ByteArrayOutputStream(); ZipOutputStream zOut= new ZipOutputStream(arrayOutputStream); ZipEntry entry= new ZipEntry(dataFile.getName()); zOut.setLevel(compression); zOut.putNextEntry(entry); zOut.write(fileArray, 0, messageSize); zOut.closeEntry(); zOut.finish(); zOut.close();
46

fileArray= arrayOutputStream.toByteArray(); compressionRatio= (short) ((double)fileArray.length / (double)messageSize * 100.0); messageSize= fileArray.length; }

writeBytes(new byte[]{(byte) compressionRatio});

if(features== UEF || features== CEF) { Cipher cipher= Cipher.getInstance("DES"); SecretKeySpec spec= new SecretKeySpec(password.substring(0, 8).getBytes(), "DES"); cipher.init(Cipher.ENCRYPT_MODE, spec); fileArray= cipher.doFinal(fileArray); messageSize= fileArray.length; }

tempByte= new byte[4]; for(i=24, j=0; i>=0; i-=8, j++) { tempInt= messageSize; tempInt>>= i; tempInt&= 0x000000FF; tempByte[j]= (byte) tempInt; }
47

writeBytes(tempByte);

writeBytes(fileArray);

DataOutputStream out= new DataOutputStream(new FileOutputStream(outputFile)); byteOut.writeTo(out); out.close(); } catch(EOFException e) { } catch(Exception e) { message= "Oops!!\nError: "+ e.toString(); e.printStackTrace(); return false; }

message= "File '"+ dataFile.getName()+ "' embedded successfully in file '"+ outputFile.getName()+ "'."; return true; }

public static boolean retrieveFile(SteganoInformation info, String password, boolean overwrite) { File dataFile= null;
48

features= info.getFeatures();

try { masterFile= info.getFile(); byteArrayIn= new byte[(int) masterFile.length()];

DataInputStream in= new DataInputStream(new FileInputStream(masterFile)); in.read(byteArrayIn, 0, (int)masterFile.length()); in.close();

messageSize= info.getDataLength(); byte[] fileArray= new byte[messageSize]; inputOutputMarker= info.getInputMarker(); readBytes(fileArray);

if(messageSize<=0) { message= "Unexpected size of embedded file: 0."; return false; }

if(features== CEF || features== UEF) { password= password.substring(0, 8);

49

byte passwordBytes[]= password.getBytes(); cipher= Cipher.getInstance("DES"); spec= new SecretKeySpec(passwordBytes, "DES"); cipher.init(Cipher.DECRYPT_MODE, spec); try { fileArray= cipher.doFinal(fileArray); } catch(Exception bp) { message= "Incorrent Password"; bp.printStackTrace(); return false; } messageSize= fileArray.length; }

if(features== CUF || features== CEF) { ByteArrayOutputStream by= new ByteArrayOutputStream(); DataOutputStream out= new DataOutputStream(by);

ZipInputStream zipIn= new ZipInputStream(new ByteArrayInputStream(fileArray)); ZipEntry entry= zipIn.getNextEntry(); dataFile= new File(entry.getName());
50

byteArrayIn= new byte[1024]; while((tempInt= zipIn.read(byteArrayIn, 0, 1024))!= -1) out.write(byteArrayIn, 0, tempInt);

zipIn.close(); out.close(); fileArray= by.toByteArray(); messageSize= fileArray.length; }

info.setDataFile(dataFile); if(dataFile.exists() && !overwrite) { message= "File Exists"; return false; }

DataOutputStream out= new DataOutputStream(new FileOutputStream(dataFile)); out.write(fileArray, 0, fileArray.length); out.close(); } catch(Exception e) { message= "Oops!!\n Error: "+ e; e.printStackTrace();

51

return false; }

message= "Retrieved file size: "+ messageSize+ " B"; return true; }

private static void embedBytes(byte[] bytes) { int size= bytes.length;

for(int i=0; i< size; i++) { byte1= bytes[i]; for(int j=6; j>=0; j-=2) { byte2= byte1; byte2>>= j; byte2&= 0x03;

byte3= byteArrayIn[inputOutputMarker]; byte3&= 0xFC; byte3|= byte2; byteOut.write(byte3); inputOutputMarker++; } }


52

private static void writeBytes(byte[] bytes) { int size= bytes.length;

for(int i=0; i< size; i++) { byteOut.write(bytes[i]); inputOutputMarker++; } }

private static void retrieveBytes(byte[] bytes) { int size= bytes.length;

for(int i=0; i< size; i++) { byte1= 0; for(int j=6; j>=0; j-=2) { byte2= byteArrayIn[inputOutputMarker]; inputOutputMarker++;

byte2&= 0x03; byte2<<= j;


53

byte1|= byte2; } bytes[i]= byte1; } }

private static void readBytes(byte[] bytes) { int size= bytes.length;

for(int i=0; i< size; i++) { bytes[i]= byteArrayIn[inputOutputMarker]; inputOutputMarker++; } } }

class SteganoInformation { private File file; private File dataFile= null; private String starter; private String version; private byte features; private short compressionRatio;
54

private int dataLength, temp; private boolean isEster= false;

private byte byteArray[], name[], byte1, byte2; private int inputMarker, i, j;

public File getFile() { return file; } public int getInputMarker() { return inputMarker; } public File getDataFile() { return dataFile; } public String getVersion() { return version; } public byte getFeatures() { return features; } public short getCompressionRatio() { return compressionRatio; } public int getDataLength() public boolean isEster() { return dataLength; } { return isEster; }

public void setDataFile(File dataFile) { this.dataFile= dataFile; } private void retrieveBytes(byte[] bytes, byte[] array, int marker) { byteArray= array; inputMarker= marker;

int size= bytes.length;

for(i=0; i< size; i++)


55

{ byte1= 0; for(j=6; j>=0; j-=2) { byte2= byteArray[inputMarker]; inputMarker++;

byte2&= 0x03; byte2<<= j; byte1|= byte2; } bytes[i]= byte1; } }

private void retrieveBytes(byte[] bytes) { int size= bytes.length;

for(i=0; i< size; i++) { byte1= 0; for(j=6; j>=0; j-=2) { byte2= byteArray[inputMarker]; inputMarker++;

56

byte2&= 0x03; byte2<<= j; byte1|= byte2; } bytes[i]= byte1; } }

private void readBytes(byte[] bytes, byte[] array, int marker) { byteArray= array; inputMarker= marker;

int size= bytes.length;

for(i=0; i< size; i++) { bytes[i]= byteArray[inputMarker]; inputMarker++; } }

private void readBytes(byte[] bytes) { int size= bytes.length;

for(i=0; i< size; i++)


57

{ bytes[i]= byteArray[inputMarker]; inputMarker++; } }

public static char[] byteToCharArray(byte[] bytes) { int size= bytes.length, i; char []chars= new char[size]; for(i=0; i<size; i++) { bytes[i]&= 0x7F; chars[i]= (char) bytes[i]; } return chars; }

public SteganoInformation(File file) { this.file= file; isEster= false;

if(!file.exists()) { starter= null; return;


58

if(file.getName().equals("Sec#x&y")) { isEster= true; return; }

byteArray= new byte[(int) file.length()]; try { DataInputStream in= new DataInputStream(new FileInputStream(file)); in.read(byteArray, 0, (int) file.length()); in.close(); } catch(Exception e) { starter= null; return; }

name= new byte[4];

String fileName= file.getName(); String fileExtension= fileName.substring(fileName.length()-3, fileName.length());

59

if(fileExtension.equalsIgnoreCase("jpg")) inputMarker= Steganography.OFFSET_JPG; else if(fileExtension.equalsIgnoreCase("png")) inputMarker= Steganography.OFFSET_PNG; else inputMarker= Steganography.OFFSET_GIF_BMP_TIF;

retrieveBytes(name, byteArray, inputMarker); dataLength= 0; for(i=24,j=0; i>=0; i-=8,j++) { temp= name[j]; temp&= 0x000000FF; temp<<= i; dataLength|= temp; } inputMarker= dataLength;

if(dataLength<0 || dataLength>file.length()) { starter= "Invalid"; return; } else starter= "KAUSHAL";

byte versionArray[]= new byte[3];


60

readBytes(versionArray, byteArray, inputMarker); char []versionTemp= byteToCharArray(versionArray); char []ver= new char[5]; for(i=0, j=0; i<5; i++) if(i== 1 || i== 3) else { ver[i]= versionTemp[j++]; } ver[i]= '.';

name= new byte[1]; readBytes(name); features= name[0];

readBytes(name); name[0]&= 0x7F; compressionRatio= name[0];

name= new byte[4]; readBytes(name); dataLength= 0; for(i=24,j=0; i>=0; i-=8,j++) { temp= name[j]; temp&= 0x000000FF; temp<<= i;
61

dataLength|= temp; } }

public boolean isValid() { if(starter.equals("SACHIN")) { return true; } else return false; } }

################# Main Client ##############

import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.awt.event.*;

public class MainClient extends WindowAdapter implements ActionListener { private JFrame mainFrame;
62

private JMenuBar private JMenu private JMenuItem private JMenuItem mnuModifyMaster;

menuBar; menuFile, menuEdit, menuView; mnuExit, mnuEmbedMessage, mnuEmbedFile; mnuRetrieveMessage, mnuRetrieveFile,

private JPanel mainPanel, panelButtons; private JLabel lblLogo; private JLabel lblFiller[]; private GridBagLayout gbl; private GridBagConstraints gbc; private MyJButton btnEmbedFile, btnRetrieveFile, btnEmbedMessage, btnRetrieveMessage; private BackEndHandler back;

private MainClient() { mainFrame= new JFrame("Steganography " + "Sachin Kumar Rathi, " + "Pradeep Kumar Maurya, " + "Kamlesh Kumar Maddheshiya" + "Krishn Kanhaiya Agrawal"); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.addWindowListener(this);

mnuExit= new JMenuItem("Exit"); mnuEmbedMessage= new JMenuItem("Embed Message"); mnuEmbedFile= new JMenuItem("Embed File"); mnuRetrieveMessage= new JMenuItem("Retrieve Message"); mnuRetrieveFile= new JMenuItem("Retrieve File"); mnuModifyMaster= new JMenuItem("Modify Master file settings");
63

mnuEmbedMessage.addActionListener(this); mnuEmbedFile.addActionListener(this); mnuRetrieveMessage.addActionListener(this); mnuRetrieveFile.addActionListener(this); mnuModifyMaster.addActionListener(this); mnuExit.addActionListener(this);

menuFile= new JMenu("File"); menuFile.add(mnuEmbedMessage); menuFile.add(mnuEmbedFile); menuFile.add(mnuRetrieveMessage); menuFile.add(mnuRetrieveFile); menuFile.add(mnuExit);

menuEdit= new JMenu("Edit"); menuEdit.add(mnuModifyMaster);

menuBar= new JMenuBar(); menuBar.add(menuFile); menuBar.add(menuEdit); mainFrame.setJMenuBar(menuBar);

mainPanel= new JPanel(); panelButtons= new JPanel();

lblFiller= new JLabel[4];


64

for(int i=0; i<4; i++) lblFiller[i]= new JLabel(" ");

gbl= new GridBagLayout(); gbc= new GridBagConstraints();

panelButtons.setBackground(Color.white); panelButtons.setLayout(gbl); panelButtons.setBorder(new TitledBorder("Supported operations"));

lblLogo= new JLabel(new ImageIcon("Images/Logo.jpg")); btnEmbedMessage= new MyJButton("Images/EmbedMessage", "Images/EmbedMessageHover"); btnEmbedFile= new MyJButton("Images/EmbedFile", "Images/EmbedFileHover"); btnRetrieveMessage= new MyJButton("Images/RetrieveMessage", "Images/RetrieveMessageHover"); btnRetrieveFile= new MyJButton("Images/RetrieveFile", "Images/RetrieveFileHover");

btnEmbedMessage.addActionListener(this); btnEmbedFile.addActionListener(this); btnRetrieveMessage.addActionListener(this); btnRetrieveFile.addActionListener(this);

gbc.weightx= 4;

gbc.weighty= 2;

gbc.fill= gbc.BOTH;

gbc.gridx= 6; gbc.gridy= 1; gbl.setConstraints(lblFiller[0], gbc); panelButtons.add(lblFiller[0]);

65

gbc.fill = gbc.BOTH; gbc.gridx= 1; gbc.weighty= 2; gbl.setConstraints(lblFiller[1], gbc); panelButtons.add(lblFiller[1]); gbc.gridy= 4;

gbc.fill= gbc.NONE; gbc.gridx= 2; gbc.weighty= 1; gbc.gridy= 6; gbl.setConstraints(btnEmbedMessage, gbc); panelButtons.add(btnEmbedMessage);

gbc.gridx= 4; gbl.setConstraints(btnRetrieveMessage, gbc); panelButtons.add(btnRetrieveMessage);

gbc.fill = gbc.BOTH; gbc.gridx= 6; gbc.weighty= 2; gbl.setConstraints(lblFiller[2], gbc); panelButtons.add(lblFiller[2]); gbc.gridy= 7;

gbc.fill= gbc.NONE; gbc.gridx= 3; gbc.weighty= 1; gbl.setConstraints(btnEmbedFile, gbc); panelButtons.add(btnEmbedFile); gbc.gridy= 9;

gbc.gridx= 5; gbl.setConstraints(btnRetrieveFile, gbc); panelButtons.add(btnRetrieveFile);

// Add the lblLogo and two Panels to the mainPanel gbl= new GridBagLayout(); mainPanel.setLayout(gbl);
66

mainPanel.setBackground(Color.white);

gbc.anchor= gbc.CENTER; gbc.gridx= 1; gbc.gridy= 1; gbc.weighty= 2; gbc.VERTICAL; gbl.setConstraints(lblLogo, gbc); mainPanel.add(lblLogo); gbc.fill=

gbc.gridy= 5; gbc.weighty= 1; gbl.setConstraints(panelButtons, gbc); mainPanel.add(panelButtons);

gbc.gridy= 6; gbc.weighty= 2; gbl.setConstraints(lblFiller[3], gbc); mainPanel.add(lblFiller[3]);

JPanel tempPanel= (JPanel) mainFrame.getContentPane(); tempPanel.add(mainPanel, BorderLayout.CENTER); tempPanel.add(new MyJLabel(" ", Color.black, Color.darkGray), BorderLayout.SOUTH);

Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); mainFrame.setSize(d.width, (int) (d.height-(d.height*.03))); mainFrame.setResizable(false); mainFrame.setVisible(true); }

public void actionPerformed(ActionEvent e)


67

{ Object source= e.getSource();

if(source== mnuEmbedMessage || source== btnEmbedMessage) { back= new BackEndHandler(this, BackEndHandler.EMBED_MESSAGE); back.start(); }

if(source== mnuRetrieveMessage || source== btnRetrieveMessage) { back= new BackEndHandler(this, BackEndHandler.RETRIEVE_MESSAGE); back.start(); }

if(source== mnuEmbedFile || source== btnEmbedFile ) { back= new BackEndHandler(this, BackEndHandler.EMBED_FILE); back.start(); }

if(source== mnuRetrieveFile || source== btnRetrieveFile ) { back= new BackEndHandler(this, BackEndHandler.RETRIEVE_FILE); back.start();


68

if(source== mnuModifyMaster) { back= new BackEndHandler(this, BackEndHandler.EDIT_MASTER); back.start(); }

if(source== mnuExit) { int result= JOptionPane.showConfirmDialog(mainFrame, "Are you sure that you want to close Steganography.", "Confirm Exit", JOptionPane.YES_NO_OPTION); if(result== JOptionPane.YES_OPTION) { JOptionPane.showMessageDialog(mainFrame, "Thanks for using Steganography.", "Steganography",JOptionPane.INFORMATION_MESSAGE); System.exit(0); } } }

public void windowClosing(WindowEvent w) { JOptionPane.showMessageDialog(mainFrame, "Thanks for using this Steganography.", "Steganography",JOptionPane.INFORMATION_MESSAGE); }

69

public static void main(String args[]) { new MainClient(); } }

############## My GUI Class #################### import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*;

class MyJButton extends JButton { public MyJButton(ImageIcon icon, ImageIcon rollOverIcon) { super(icon); setRolloverIcon(rollOverIcon); setPressedIcon(icon); setBackground(Color.white); }

public MyJButton(String icon, String rollOverIcon) {


70

super(new ImageIcon(icon)); setRolloverIcon(new ImageIcon(rollOverIcon)); setPressedIcon(new ImageIcon(icon)); setBorderPainted(false); } }

class MyJLabel extends JLabel { public MyJLabel(String caption, Color foreground, Color background) { super(caption); setForeground(foreground); setBackground(background); }

public MyJLabel(String caption, Font font, Color foreground, Color background) { super(caption); setForeground(foreground); setBackground(background); setFont(font); } }

class MyJTextField extends JTextField {


71

public MyJTextField(String caption, int size, Color foreground, Color background) { super(caption, size); setForeground(foreground); setBackground(background); }} ########### Embed Message GUI ############### import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.awt.event.*; import java.io.File; import java.util.Hashtable;

public class EmbedMessageGUI extends JFrame implements ActionListener, ItemListener { BackEndHandler client;

private JLabel lblMaster, lblOutput, lblMasterSize, lblOutputSize, lblMessage;; private JLabel lblMasterFileSize, lblOutputFileSize, lblFiller[]; private JLabel lblCompression, lblPassword; private JCheckBox chkCompress, chkEncrypt; private JSlider sliderCompression; private JPasswordField txtPassword; private JTextField txtMasterFile, txtOutputFile; private JTextArea txtMessage;
72

private JScrollPane scrollPane; private JButton btnGo, btnCancel, btnChangeMasterFile, btnChangeOutputFile;

public EmbedMessageGUI(BackEndHandler client) { super("Embedding message - Steganography."); setDefaultCloseOperation(DISPOSE_ON_CLOSE);

this.client= client;

lblFiller= new JLabel[11]; for(int i=0; i<11; i++) lblFiller[i]= new JLabel(" ");

Font arialFont= new Font("Arial", Font.PLAIN, 11);

lblMaster= new MyJLabel("Master file", arialFont, Color.black, Color.lightGray); lblOutput= new MyJLabel("Output file", arialFont, Color.black, Color.lightGray); lblMasterSize= new MyJLabel("Size: ", arialFont, Color.black, Color.lightGray); lblOutputSize= new MyJLabel("Size: ", arialFont, Color.black, Color.lightGray); txtMasterFile= new MyJTextField(client.getMasterFile().getName(), 13, Color.blue, Color.lightGray); txtMasterFile.setEditable(false); lblMasterFileSize= new MyJLabel(""+ client.getMasterFile().length()/1024+ " Kb", arialFont, Color.red, Color.gray);

73

txtOutputFile= new MyJTextField(client.getOutputFile().getName(), 13, Color.blue, Color.lightGray); txtOutputFile.setEditable(false); lblOutputFileSize= new MyJLabel(lblMasterFileSize.getText(), arialFont, Color.red, Color.gray); lblMessage= new MyJLabel("Message:", arialFont, Color.black, Color.lightGray);

txtMessage= new JTextArea(12, 64); scrollPane= new JScrollPane(txtMessage);

btnChangeMasterFile= new JButton("Change"); btnChangeOutputFile= new JButton("Change"); btnGo= new JButton(" Go "); btnCancel= new JButton(" Close ");

JPanel panelFiles= new JPanel(); GridBagLayout gbl= new GridBagLayout(); GridBagConstraints gbc= new GridBagConstraints(); panelFiles.setLayout(gbl);

gbc.insets= new Insets(2,2,2,2); gbc.gridx= 1; gbc.gridy= 1; gbl.setConstraints(lblMaster, gbc); panelFiles.add(lblMaster); gbc.gridx= 2; gbl.setConstraints(txtMasterFile, gbc); panelFiles.add(txtMasterFile); gbc.gridx= 3; gbl.setConstraints(lblMasterSize, gbc);
74

panelFiles.add(lblMasterSize); gbc.gridx= 4; gbl.setConstraints(lblMasterFileSize, gbc); panelFiles.add(lblMasterFileSize); gbc.gridx= 5; gbl.setConstraints(lblFiller[0], gbc); panelFiles.add(lblFiller[0]); gbc.gridx= 6; gbl.setConstraints(lblOutput, gbc); panelFiles.add(lblOutput); gbc.gridx= 7; gbl.setConstraints(txtOutputFile, gbc); panelFiles.add(txtOutputFile); gbc.gridx= 8; gbl.setConstraints(lblOutputSize, gbc); panelFiles.add(lblOutputSize); gbc.gridx= 9; gbl.setConstraints(lblOutputFileSize, gbc); panelFiles.add(lblOutputFileSize);

gbc.gridx= 2; gbc.gridy= 2; gbl.setConstraints(btnChangeMasterFile, gbc); panelFiles.add(btnChangeMasterFile); gbc.gridx= 7; gbl.setConstraints(btnChangeOutputFile, gbc); panelFiles.add(btnChangeOutputFile);

// Setup panelFeatures lblCompression= new JLabel("Compression level"); lblPassword= new JLabel("Password (Minimum 8 chars)"); chkCompress= new JCheckBox("Compress"); chkEncrypt= new JCheckBox("Encrypt"); sliderCompression= new JSlider(0, 9, 5); sliderCompression.setPaintTicks(true);

75

sliderCompression.setPaintLabels(true); sliderCompression.setSnapToTicks(true); sliderCompression.setMajorTickSpacing(1); sliderCompression.setForeground(Color.blue); Hashtable h= new Hashtable(); h.put(new Integer(0), new JLabel("0", JLabel.CENTER)); h.put(new Integer(5), new JLabel("5", JLabel.CENTER)); h.put(new Integer(9), new JLabel("9", JLabel.CENTER)); sliderCompression.setLabelTable(h);

txtPassword= new JPasswordField(9); chkCompress.addItemListener(this); chkEncrypt.addItemListener(this); lblCompression.setEnabled(false); sliderCompression.setEnabled(false); lblPassword.setEnabled(false); txtPassword.setEnabled(false);

JPanel panelCompression1= new JPanel(); new BoxLayout(panelCompression1, BoxLayout.X_AXIS); panelCompression1.add(chkCompress); panelCompression1.add(lblCompression);

JPanel panelCompression2= new JPanel(); new BoxLayout(panelCompression2, BoxLayout.X_AXIS);

76

panelCompression2.add(new MyJLabel("Low", arialFont, Color.blue, Color.lightGray)); panelCompression2.add(sliderCompression); panelCompression2.add(new MyJLabel("High", arialFont, Color.blue, Color.lightGray));

JPanel panelCompression= new JPanel(); gbl= new GridBagLayout(); panelCompression.setLayout(gbl); gbc.gridx= 1; gbc.gridy=1; gbl.setConstraints(panelCompression1, gbc); panelCompression.add(panelCompression1); gbc.gridy= 2; gbl.setConstraints(panelCompression2, gbc); panelCompression.add(panelCompression2);

JPanel panelEncryption= new JPanel(); new BoxLayout(panelEncryption, BoxLayout.X_AXIS); panelEncryption.add(chkEncrypt); panelEncryption.add(lblPassword); panelEncryption.add(txtPassword);

JPanel panelFeatures= new JPanel(); new BoxLayout(panelFeatures, BoxLayout.X_AXIS); panelFeatures.add(panelCompression); panelFeatures.add(panelEncryption);

JPanel panelText= new JPanel(); gbl= new GridBagLayout(); panelText.setLayout(gbl);


77

gbc.gridy= 2; gbc.anchor= gbc.WEST; gbl.setConstraints(lblMessage, gbc); panelText.add(lblMessage); gbc.gridy= 3; gbc.anchor= gbc.CENTER; gbl.setConstraints(scrollPane, gbc); panelText.add(scrollPane);

JPanel panelButtons= new JPanel(); gbl= new GridBagLayout(); panelButtons.setLayout(gbl); gbc.anchor= gbc.CENTER; gbl.setConstraints(btnGo, gbc); panelButtons.add(btnGo); gbc.gridy= 2;gbl.setConstraints(lblFiller[3], gbc); panelButtons.add(lblFiller[3]); gbc.gridy= 4;gbl.setConstraints(lblFiller[4], gbc); panelButtons.add(lblFiller[4]); gbc.gridy= 5;gbl.setConstraints(btnCancel, gbc); panelButtons.add(btnCancel); gbc.gridx= 1; gbc.gridy= 1;

JPanel panelLower= new JPanel(); new BoxLayout(panelLower, BoxLayout.X_AXIS); panelLower.add(panelText); panelLower.add(panelButtons);

JPanel mainPanel= new JPanel(); new BoxLayout(mainPanel, BoxLayout.Y_AXIS); mainPanel.add(panelFiles);


78

mainPanel.add(lblFiller[10]); mainPanel.add(panelFeatures); mainPanel.add(panelLower);

setContentPane(mainPanel);

btnChangeMasterFile.addActionListener(this); btnChangeOutputFile.addActionListener(this); btnGo.addActionListener(this); btnCancel.addActionListener(this);

Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); int width= (int)(0.91* d.width); int height= (int)(0.935* d.height); setSize(width, height); setLocation((d.width- width)/2, (d.height- height)/2); //setResizable(false); setVisible(true); }

public void actionPerformed(ActionEvent e) { Object source= e.getSource();

if(source== btnChangeMasterFile) { client.chooseMasterFile();


79

txtMasterFile.setText(client.getMasterFile().getName()); lblMasterFileSize.setText(""+ client.getMasterFile().length()/1024+ "Kb"); lblOutputFileSize.setText(lblMasterFileSize.getText()); }

if(source== btnChangeOutputFile) { client.chooseOutputFile(); txtOutputFile.setText(client.getOutputFile().getName()); }

if(source== btnCancel) dispose();

if(source== btnGo) { int compression= -1; String password= null;

if(txtMessage.getText().length()<1) { JOptionPane.showMessageDialog(this, "Please enter the message\nYou can also paste the message on clipboard using\nCtrl+V combination.", "Empty message!", JOptionPane.WARNING_MESSAGE); return; }

80

if(chkCompress.isSelected()) compression= sliderCompression.getValue();

if(chkEncrypt.isSelected()) { password= new String(txtPassword.getPassword()); if(password.length()<8) { JOptionPane.showMessageDialog(this, "Password needs to be a minimum of 8 Characters!", "Invalid password!", JOptionPane.WARNING_MESSAGE); return; } }

if(client.getOutputFile().exists()) { int result2= JOptionPane.showConfirmDialog(null, "File "+ client.getOutputFile().getName()+ " already exists!\nWould you like to OVERWRITE it?", "File already exists!", JOptionPane.YES_NO_OPTION); if(!(result2== JOptionPane.YES_OPTION)) if(!client.chooseOutputFile()) return; }

if(Steganography.embedMessage(client.getMasterFile(), client.getOutputFile(), txtMessage.getText(), compression, password)) JOptionPane.showMessageDialog(this, Steganography.getMessage(), "Operation Successful", JOptionPane.INFORMATION_MESSAGE);
81

else JOptionPane.showMessageDialog(this, Steganography.getMessage(), "Operation Unsuccessful", JOptionPane.ERROR_MESSAGE); } }

public void itemStateChanged(ItemEvent e) { if(e.getSource()== chkCompress) { if(chkCompress.isSelected()) { lblCompression.setEnabled(true); sliderCompression.setEnabled(true); } else { lblCompression.setEnabled(false); sliderCompression.setEnabled(false); } } else { if(chkEncrypt.isSelected()) { lblPassword.setEnabled(true); txtPassword.setEnabled(true);
82

} else { lblPassword.setEnabled(false); txtPassword.setEnabled(false); } } } }

############ Embed File GUI ############### import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.File; import java.util.Hashtable;

public class EmbedFileGUI extends JFrame implements ActionListener, ItemListener { BackEndHandler client;

private JLabel lblMaster, lblOutput, lblData, lblMasterSize, lblOutputSize, lblMessage;; private JLabel lblMasterFileSize, lblOutputFileSize, lblStatus; private JLabel lblDataSize, lblDataFileSize; private JLabel lblCompression, lblPassword;

83

private JCheckBox chkCompress, chkEncrypt; private JSlider sliderCompression; private JPasswordField txtPassword; private JTextField txtMasterFile, txtOutputFile, txtDataFile; private JScrollPane scrollPane; private JButton btnGo, btnCancel; private JButton btnChangeMasterFile, btnChangeOutputFile, btnChangeDataFile;

public EmbedFileGUI(BackEndHandler client) { super("Embedding file - Steganography."); setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.client= client;

Font arialFont= new Font("Arial", Font.PLAIN, 11); lblMaster= new JLabel("Master file"); lblOutput= new JLabel("Output file"); lblData= new JLabel("Data file");

lblMasterSize= new JLabel("Size: "); lblOutputSize= new JLabel("Size: "); lblDataSize= new JLabel("Size: "); txtMasterFile= new MyJTextField(client.getMasterFile().getName(), 13, Color.blue, Color.lightGray); txtMasterFile.setEditable(false); lblMasterFileSize= new MyJLabel(""+ client.getMasterFile().length()/1024+ " Kb", arialFont, Color.red, Color.gray);

84

txtOutputFile= new MyJTextField(client.getOutputFile().getName(), 13, Color.blue, Color.lightGray); txtOutputFile.setEditable(false); lblOutputFileSize= new MyJLabel(lblMasterFileSize.getText(), arialFont, Color.red, Color.gray);

txtDataFile= new MyJTextField(client.getDataFile().getName(), 13, Color.blue, Color.lightGray); txtDataFile.setEditable(false); lblDataFileSize= new MyJLabel(""+ client.getDataFile().length()/1024+ " Kb", arialFont, Color.red, Color.gray);

btnChangeMasterFile= new JButton("Change"); btnChangeOutputFile= new JButton("Change"); btnChangeDataFile= new JButton("Change");

btnGo= new JButton(" Go "); btnCancel= new JButton(" Close ");

lblCompression= new MyJLabel("Compression level", arialFont, Color.black, Color.lightGray); lblPassword= new MyJLabel("Password (Minimum 8 chars)", arialFont, Color.black, Color.lightGray); chkCompress= new JCheckBox("Compress"); chkEncrypt= new JCheckBox("Encrypt");

sliderCompression= new JSlider(0, 9, 5); sliderCompression.setForeground(Color.blue); sliderCompression.setPaintTicks(true); sliderCompression.setPaintLabels(true);

85

sliderCompression.setSnapToTicks(true); sliderCompression.setMajorTickSpacing(1); Hashtable h= new Hashtable(); h.put(new Integer(0), new JLabel("0".toString(), JLabel.CENTER)); h.put(new Integer(5), new JLabel("5".toString(), JLabel.CENTER)); h.put(new Integer(9), new JLabel("9".toString(), JLabel.CENTER)); sliderCompression.setLabelTable(h);

txtPassword= new JPasswordField(9); chkCompress.addItemListener(this); chkEncrypt.addItemListener(this); lblCompression.setEnabled(false); sliderCompression.setEnabled(false); lblPassword.setEnabled(false); txtPassword.setEnabled(false);

JPanel file1= new JPanel(); new BoxLayout(file1, BoxLayout.X_AXIS); file1.add(lblMaster); file1.add(txtMasterFile); file1.add(lblMasterSize); file1.add(lblMasterFileSize); file1.add(btnChangeMasterFile);

JPanel file2= new JPanel(); new BoxLayout(file2, BoxLayout.X_AXIS);


86

file2.add(lblOutput); file2.add(txtOutputFile); file2.add(lblOutputSize); file2.add(lblOutputFileSize); file2.add(btnChangeOutputFile);

JPanel file3= new JPanel(); new BoxLayout(file3, BoxLayout.X_AXIS); file3.add(lblData); file3.add(txtDataFile); file3.add(lblDataSize); file3.add(lblDataFileSize); file3.add(btnChangeDataFile);

JPanel panelFiles= new JPanel(); GridBagLayout gbl= new GridBagLayout(); GridBagConstraints gbc= new GridBagConstraints(); panelFiles.setLayout(gbl); JLabel lblFiller; gbc.anchor= gbc.WEST; gbl.setConstraints(file1, gbc); panelFiles.add(file1); lblFiller= new JLabel(" "); gbc.gridy= 2; gbl.setConstraints(lblFiller, gbc); gbc.gridx=1; gbc.gridy= 1;

panelFiles.add(lblFiller); gbc.gridy= 3; panelFiles.add(file2);


87

gbl.setConstraints(file2, gbc);

lblFiller= new JLabel(" "); gbc.gridy= 4; gbl.setConstraints(lblFiller, gbc);

panelFiles.add(lblFiller); gbc.gridy= 5; panelFiles.add(file3); gbl.setConstraints(file3, gbc);

JPanel panelFeatures1a= new JPanel(); new BoxLayout(panelFeatures1a, BoxLayout.X_AXIS); panelFeatures1a.add(chkCompress); panelFeatures1a.add(lblCompression);

JPanel panelFeatures1b= new JPanel(); new BoxLayout(panelFeatures1b, BoxLayout.X_AXIS); panelFeatures1b.add(new MyJLabel("Low", arialFont, Color.blue, Color.lightGray)); panelFeatures1b.add(sliderCompression); panelFeatures1b.add(new MyJLabel("High", arialFont, Color.blue, Color.lightGray));

JPanel panelFeatures1= new JPanel(); gbl= new GridBagLayout(); panelFeatures1.setLayout(gbl); gbc.gridx= 1; gbc.gridy= 1; gbl.setConstraints(panelFeatures1a, gbc); panelFeatures1.add(panelFeatures1a); gbc.gridy= 2; gbl.setConstraints(panelFeatures1b, gbc); panelFeatures1.add(panelFeatures1b);

JPanel panelFeatures2= new JPanel();


88

new BoxLayout(panelFeatures2, BoxLayout.X_AXIS); panelFeatures2.add(chkEncrypt); panelFeatures2.add(lblPassword); panelFeatures2.add(txtPassword);

JPanel panelFeatures= new JPanel(); gbl= new GridBagLayout(); panelFeatures.setLayout(gbl); gbc.anchor= gbc.WEST; gbc.gridx=1; gbc.gridy= 1;

gbl.setConstraints(panelFeatures1, gbc); panelFeatures.add(panelFeatures1); lblFiller= new JLabel(" "); gbc.gridy= 2; gbl.setConstraints(lblFiller, gbc);

panelFeatures.add(lblFiller); gbc.gridy= 3; gbl.setConstraints(panelFeatures2, gbc);

panelFeatures.add(panelFeatures2);

JPanel panelButtons= new JPanel(); gbl= new GridBagLayout(); panelButtons.setLayout(gbl); gbc.anchor= gbc.WEST; gbc.gridx=1; gbc.gridy= 1;

gbl.setConstraints(btnGo, gbc); panelButtons.add(btnGo); lblFiller= new JLabel(" "); gbc.gridy= 2; gbl.setConstraints(lblFiller, gbc);

panelButtons.add(lblFiller); lblFiller= new JLabel(" ");


89

gbc.gridy= 4;

gbl.setConstraints(lblFiller, gbc);

panelButtons.add(lblFiller); gbc.gridy= 5; gbl.setConstraints(btnCancel, gbc);

panelButtons.add(btnCancel);

JPanel mainPanel= new JPanel(); new BoxLayout(mainPanel, BoxLayout.Y_AXIS); mainPanel.add(panelFiles); mainPanel.add(new JLabel(" ")); mainPanel.add(panelFeatures); mainPanel.add(new JLabel(" ")); mainPanel.add(panelButtons); setContentPane(mainPanel);

btnChangeMasterFile.addActionListener(this); btnChangeOutputFile.addActionListener(this); btnChangeDataFile.addActionListener(this); btnGo.addActionListener(this); btnCancel.addActionListener(this);

Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); int width= (int)(0.7* d.width); int height= (int)(0.85* d.height); setSize(width, height); setLocation((d.width- width)/2, (d.height- height)/2); //setResizable(false); setVisible(true);
90

public void actionPerformed(ActionEvent e) { Object source= e.getSource();

if(source== btnChangeMasterFile) { client.chooseMasterFile(); txtMasterFile.setText(client.getMasterFile().getName()); lblMasterFileSize.setText(""+ client.getMasterFile().length()/1024+ "Kb"); lblOutputFileSize.setText(lblMasterFileSize.getText()); }

if(source== btnChangeOutputFile) { client.chooseOutputFile(); txtOutputFile.setText(client.getOutputFile().getName()); }

if(source== btnChangeDataFile) { client.chooseDataFile(); txtDataFile.setText(client.getDataFile().getName()); lblDataFileSize.setText(""+ client.getDataFile().length()/1024+ "Kb"); }


91

if(source== btnCancel) dispose();

if(source== btnGo) { int compression= sliderCompression.getValue(); String password= null;

if(chkEncrypt.isSelected()) { password= new String(txtPassword.getPassword()); if(password.length()<8) { JOptionPane.showMessageDialog(this, "Password needs to be a minimum of 8 Characters!", "Invalid password!", JOptionPane.WARNING_MESSAGE); return; } }

if(client.getOutputFile().exists()) { int result2= JOptionPane.showConfirmDialog(null, "File "+ client.getOutputFile().getName()+ " already exists!\nWould you like to OVERWRITE it?", "File already exists!", JOptionPane.YES_NO_OPTION); if(!(result2== JOptionPane.YES_OPTION)) if(!client.chooseOutputFile()) return;
92

if(Steganography.embedFile(client.getMasterFile(), client.getOutputFile(), client.getDataFile(), compression, password)) JOptionPane.showMessageDialog(this, Steganography.getMessage(), "Operation Successful", JOptionPane.INFORMATION_MESSAGE); else JOptionPane.showMessageDialog(this, Steganography.getMessage(), "Operation Unsuccessful", JOptionPane.ERROR_MESSAGE); } }

public void itemStateChanged(ItemEvent e) { if(e.getSource()== chkCompress) { if(chkCompress.isSelected()) { lblCompression.setEnabled(true); sliderCompression.setEnabled(true); } else { lblCompression.setEnabled(false); sliderCompression.setEnabled(false); } }
93

else { if(chkEncrypt.isSelected()) { lblPassword.setEnabled(true); txtPassword.setEnabled(true); } else { lblPassword.setEnabled(false); txtPassword.setEnabled(false); } } } }

############ My File Choose Class ########### import javax.swing.*; import java.awt.*; import java.io.File; import java.util.*; import javax.swing.filechooser.*; import java.beans.*;

class MyFileFilter extends FileFilter {

private static String TYPE_UNKNOWN = "Type Unknown";


94

private static String HIDDEN_FILE = "Hidden File";

private Hashtable filters = null; private String description = null; private String fullDescription = null; private boolean useExtensionsInDescription = true;

public MyFileFilter() { this.filters = new Hashtable(); }

public MyFileFilter(String extension) { this(extension,null); }

public MyFileFilter(String extension, String description) { this(); if(extension!=null) addExtension(extension); if(description!=null) setDescription(description); }

public MyFileFilter(String[] filters) { this(filters, null); }

public MyFileFilter(String[] filters, String description) { this();


95

for (int i = 0; i < filters.length; i++) { addExtension(filters[i]); } if(description!=null) setDescription(description); }

public boolean accept(File f) { if(f != null) { if(f.isDirectory()) { return true; } String extension = getExtension(f); if(extension != null && filters.get(getExtension(f)) != null) { return true; }; } return false; }

public String getExtension(File f) { if(f != null) { String filename = f.getName(); int i = filename.lastIndexOf('.'); if(i>0 && i<filename.length()-1) { return filename.substring(i+1).toLowerCase(); }; }
96

return null; }

public void addExtension(String extension) { if(filters == null) { filters = new Hashtable(5); } filters.put(extension.toLowerCase(), this); fullDescription = null; }

public String getDescription() { if(fullDescription == null) { if(description == null || isExtensionListInDescription()) { fullDescription = description==null ? "(" : description + " ("; Enumeration extensions = filters.keys(); if(extensions != null) { fullDescription += "." + (String) extensions.nextElement(); while (extensions.hasMoreElements()) { fullDescription += ", ." + (String) extensions.nextElement(); } } fullDescription += ")"; } else { fullDescription = description; }
97

} return fullDescription; }

public void setDescription(String description) { this.description = description; fullDescription = null; }

public void setExtensionListInDescription(boolean b) { useExtensionsInDescription = b; fullDescription = null; }

public boolean isExtensionListInDescription() { return useExtensionsInDescription; } }

class FilePreviewer extends JComponent implements PropertyChangeListener { ImageIcon thumbnail = null;

public FilePreviewer(JFileChooser fc) { setPreferredSize(new Dimension(100, 50));


98

fc.addPropertyChangeListener(this); }

public void loadImage(File f) { if (f == null) { thumbnail = null; } else { ImageIcon tmpIcon = new ImageIcon(f.getPath()); if(tmpIcon.getIconWidth() > 90) { thumbnail = new ImageIcon( tmpIcon.getImage().getScaledInstance(90, -1, Image.SCALE_DEFAULT)); } else { thumbnail = tmpIcon; } } }

public void propertyChange(PropertyChangeEvent e) {

99

String prop = e.getPropertyName(); if(prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) { if(isShowing()) { loadImage((File) e.getNewValue()); repaint(); } } }

public void paint(Graphics g) { if(thumbnail!=null) { int xpos= (getWidth()- thumbnail.getIconWidth())/2; int ypos= (getHeight()- thumbnail.getIconHeight())/2; g.drawImage(thumbnail.getImage(), xpos, ypos, null); } } }

class MyFileView extends FileView { private Hashtable icons = new Hashtable(5); private Hashtable fileDescriptions = new Hashtable(5); private Hashtable typeDescriptions = new Hashtable(5);

100

public String getName(File f) { return null; }

public void putDescription(File f, String fileDescription) { fileDescriptions.put(fileDescription, f); }

public String getDescription(File f) { return (String) fileDescriptions.get(f); };

public void putTypeDescription(String extension, String typeDescription) { typeDescriptions.put(typeDescription, extension); }

public void putTypeDescription(File f, String typeDescription) { putTypeDescription(getExtension(f), typeDescription); }

public String getTypeDescription(File f) { return (String) typeDescriptions.get(getExtension(f)); }

public String getExtension(File f) { String name = f.getName(); if(name != null) {


101

int extensionIndex = name.lastIndexOf('.'); if(extensionIndex < 0) { return null; } return name.substring(extensionIndex+1).toLowerCase(); } return null; }

public void putIcon(String extension, Icon icon) { icons.put(extension, icon); }

public Icon getIcon(File f) { Icon icon = null; String extension = getExtension(f); if(extension != null) { icon = (Icon) icons.get(extension); } return icon; }

public Boolean isHidden(File f) { String name = f.getName(); if(name != null && !name.equals("") && name.charAt(0) == '.') { return Boolean.TRUE; } else {
102

return Boolean.FALSE; } };} ################# Pre Retrieve GUI ############## import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.awt.event.*; import java.io.File;

public class PreRetrieveGUI extends JFrame implements ActionListener { public static boolean RETRIEVE_MESSAGE= true; public static boolean RETRIEVE_FILE= false; private JPanel panel; private JLabel lblMaster, lblMasterFile, lblVersion, lblVersionUsed; private JLabel lblContains, lblContainsWhat, lblCompressed, lblCompressedStatus; private JLabel lblCompression, lblCompressionRatio; private JLabel lblEncrypted, lblEncryptedStatus, lblRequested, lblRequestedOperation; private JLabel lblFiller[]; private JButton btnGo, btnCancel;

private boolean operation; private SteganoInformation info;

public PreRetrieveGUI(SteganoInformation info, boolean operation)


103

{ super("Master file information"); setDefaultCloseOperation(DISPOSE_ON_CLOSE);

this.operation= operation; this.info= info; Font comicFont= new Font("Comic sans MS", Font.PLAIN, 11); Font arialFont= new Font("Arial", Font.PLAIN, 11);

lblMaster= new MyJLabel("Master file", arialFont, Color.black, Color.gray); lblMasterFile= new MyJLabel(info.getFile().getName(), comicFont, Color.blue, Color.gray); lblVersion= new MyJLabel("Steganography Used", arialFont, Color.black, Color.gray); lblVersionUsed= new MyJLabel(info.getVersion(), comicFont, Color.blue, Color.gray); lblContains= new MyJLabel("Contains", arialFont, Color.black, Color.gray);

byte features= info.getFeatures(); if(features == Steganography.UUM || features== Steganography.UEM || features == Steganography.CUM || features== Steganography.CEM) lblContainsWhat= new MyJLabel("Embedded message", comicFont, Color.blue, Color.gray); else lblContainsWhat= new MyJLabel("Embedded file", comicFont, Color.blue, Color.gray);

104

lblCompressed= new MyJLabel("Compressed", arialFont, Color.black, Color.gray); lblCompression= new MyJLabel("Compression ratio", arialFont, Color.black, Color.gray); lblCompressionRatio= new MyJLabel(""+ info.getCompressionRatio()+ " %", comicFont, Color.blue, Color.gray); if(features == Steganography.CUM || features== Steganography.CUF || features == Steganography.CEM || features== Steganography.CEF) lblCompressedStatus= new MyJLabel("YES", comicFont, Color.blue, Color.gray); else { lblCompressedStatus= new MyJLabel("NO", comicFont, Color.blue, Color.gray); lblCompression.setEnabled(false); lblCompressionRatio.setEnabled(false); }

lblEncrypted= new MyJLabel("Encrypted", arialFont, Color.black, Color.gray); if(features== Steganography.UEM || features== Steganography.CEM || features== Steganography.UEF || features== Steganography.CEF) lblEncryptedStatus= new MyJLabel("YES", comicFont, Color.blue, Color.gray); else lblEncryptedStatus= new MyJLabel("NO", comicFont, Color.blue, Color.gray);

105

lblRequested= new MyJLabel("Requested operation", arialFont, Color.black, Color.gray);

if(operation== RETRIEVE_MESSAGE) lblRequestedOperation= new MyJLabel("Retrieve message", comicFont, Color.blue, Color.gray); else lblRequestedOperation= new MyJLabel("Retrieve File", comicFont, Color.blue, Color.gray);

lblFiller= new JLabel[2]; for(int i=0; i<2; i++) lblFiller[i]= new JLabel(" btnGo= new JButton("Go"); btnCancel= new JButton("Cancel"); btnGo.addActionListener(this); btnCancel.addActionListener(this); ");

JPanel panelUpper= new JPanel(); GridBagLayout gbl= new GridBagLayout(); GridBagConstraints gbc= new GridBagConstraints(); panelUpper.setLayout(gbl);

gbc.anchor= gbc.WEST; gbc.gridx= 1; gbc.gridy= 1; panelUpper.add(lblMaster); gbc.gridx= 3; gbl.setConstraints(lblMasterFile, gbc); panelUpper.add(lblMasterFile); gbc.gridx= 1; gbc.gridy= 2; gbl.setConstraints(lblVersion, gbc);
106

gbl.setConstraints(lblMaster, gbc);

panelUpper.add(lblVersion); gbc.gridx= 3; gbl.setConstraints(lblVersionUsed, gbc); panelUpper.add(lblVersionUsed); gbc.gridx= 1; gbc.gridy= 3; panelUpper.add(lblContains); gbc.gridx= 3; gbl.setConstraints(lblContainsWhat, gbc); panelUpper.add(lblContainsWhat); gbc.gridx= 1; gbc.gridy= 4; gbl.setConstraints(lblCompressed, gbc); gbl.setConstraints(lblContains, gbc);

panelUpper.add(lblCompressed); gbc.gridx= 3; gbl.setConstraints(lblCompressedStatus, gbc); panelUpper.add(lblCompressedStatus); gbc.gridx= 1; gbc.gridy= 5; gbl.setConstraints(lblCompression, gbc);

panelUpper.add(lblCompression); gbc.gridx= 3; gbl.setConstraints(lblCompressionRatio, gbc); panelUpper.add(lblCompressionRatio); gbc.gridx= 1; gbc.gridy= 6; gbl.setConstraints(lblEncrypted, gbc);

panelUpper.add(lblEncrypted); gbc.gridx= 3; gbl.setConstraints(lblEncryptedStatus, gbc); panelUpper.add(lblEncryptedStatus);

gbc.gridx= 2; gbc.gridy= 7; panelUpper.add(lblFiller[0]); gbc.gridx= 1; gbc.gridy= 8;

gbl.setConstraints(lblFiller[0], gbc);

gbl.setConstraints(lblRequested, gbc);

panelUpper.add(lblRequested); gbc.gridx= 3; gbl.setConstraints(lblRequestedOperation, gbc); panelUpper.add(lblRequestedOperation);

107

JPanel panelLower= new JPanel(); new BoxLayout(panelLower, BoxLayout.X_AXIS); panelLower.add(btnGo); panelLower.add(new JLabel(" panelLower.add(btnCancel); "));

JPanel mainPanel= (JPanel) getContentPane(); gbl= new GridBagLayout(); mainPanel.setLayout(gbl); gbc.anchor= gbc.CENTER; gbc.gridx= 1; gbc.gridy= 1; gbl.setConstraints(panelUpper, gbc); mainPanel.add(panelUpper); gbc.gridy= 2; gbl.setConstraints(lblFiller[1], gbc); mainPanel.add(lblFiller[1]); gbc.gridy= 3; gbl.setConstraints(panelLower, gbc); mainPanel.add(panelLower);

Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); int width= (int)(0.4* d.width); int height= (int)(0.5* d.height); setSize(width, height); setLocation((d.width- width)/2, (d.height- height)/2); setResizable(false); setVisible(true); }

108

public void actionPerformed(ActionEvent e) { if(e.getSource()== btnCancel) dispose(); else { int result; String password= null;

if(lblEncryptedStatus.getText().equals("YES")) { Object message[]= new Object[3]; message[0]= new MyJLabel("This is an encrypted zone.", Color.red, Color.gray); message[1]= new JLabel("Please enter password to continue."); JPasswordField pass= new JPasswordField(10); message[2]= pass;

String options[]= {"Retrieve now", "Cancel"};

do { result= JOptionPane.showOptionDialog(null, message, "Encrypted zone" , JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);

if(result== 1)
109

return; password= new String(pass.getPassword()); if(password.length()<8) JOptionPane.showMessageDialog(null, "Length of password should be atleast 8 Characters", "Invalid password", JOptionPane.OK_OPTION); }while(password.length()<8); }

if(operation== RETRIEVE_MESSAGE file")) {

&&

lblContainsWhat.getText().equals("Embedded

result= JOptionPane.showConfirmDialog(null, "This file contains an embedded file\nWhereas you have requested to retrieve a message.\n\nWould you like to retrieve the file instead?", "Incorrect request!", JOptionPane.YES_NO_OPTION); if(result== JOptionPane.NO_OPTION) dispose(); }

if(operation== RETRIEVE_FILE && lblContainsWhat.getText().equals("Embedded message")) { result= JOptionPane.showConfirmDialog(null, "This file contains an embedded message\nWhereas you have requested to retrieve a file.\n\nWould you like to retrieve the message instead?", "Incorrect request!", JOptionPane.YES_NO_OPTION); if(result== JOptionPane.NO_OPTION) {
110

dispose(); return; } }

if(lblContainsWhat.getText().equals("Embedded message")) { String message= Steganography.retrieveMessage(info, password); if(message!=null && !message.equals("#FAILED#")) new MessageDisplay(message, info.getFile().getName()); else { message= Steganography.getMessage(); if(message!= null && message.equals("Incorrent Password")) JOptionPane.showMessageDialog(null, "Incorrect Password Specified!\nMake sure that Caps lock is not on.", "Invalid password!", JOptionPane.WARNING_MESSAGE); else JOptionPane.showMessageDialog(null, "Error!\n"+ Steganography.getMessage(), "Oops, Error!", JOptionPane.ERROR_MESSAGE); } } else { boolean res= Steganography.retrieveFile(info, password, false);
111

if(!res) { String message= Steganography.getMessage(); if(message!= null) if(message.equals("Incorrent Password")) JOptionPane.showMessageDialog(null, "Incorrect Password Specified!\nMake sure that Caps lock is not on.", "Invalid password!", JOptionPane.WARNING_MESSAGE); else if(message.equals("File Exists")) { result= JOptionPane.showConfirmDialog(null, "The data file '"+ info.getDataFile().getName()+ "' being retrieved already exists!\nWould you like to OVERWRITE it?", "Confirm OVERWRITE", JOptionPane.YES_NO_OPTION); if(result== JOptionPane.NO_OPTION) return;

Steganography.retrieveFile(info, password, true); showFile(info); } else JOptionPane.showMessageDialog(null, "Error!\n"+ Steganography.getMessage(), "Oops, Error!", JOptionPane.ERROR_MESSAGE); } else showFile(info);

112

} } }

private void showFile(SteganoInformation info) { int result= JOptionPane.showConfirmDialog(null, "The data file '"+ info.getDataFile().getName()+ "' has been successfully retrieved as\n"+ info.getDataFile().getPath()+ "\n\nWould you like to open it now?", "Operation successful", JOptionPane.YES_NO_OPTION); if(result== JOptionPane.YES_OPTION) { String osName= System.getProperty("os.name"); if(osName.length()>=7) osName= osName.substring(0, 7); if(osName.compareToIgnoreCase("windows")== 0) try { Runtime.getRuntime().exec("explorer "+ info.getDataFile().getPath()); } catch(Exception ex) { JOptionPane.showMessageDialog(null, "Oops!! Error!\n"+ ex, "Error!", JOptionPane.WARNING_MESSAGE); } else JOptionPane.showMessageDialog(null, "Sorry!\nI just discovered that you are not running a Windows operating system.\nI will not be able to

113

open this file for you at this time.", "Non windows OS!", JOptionPane.INFORMATION_MESSAGE); } } }

class MessageDisplay extends JFrame { public MessageDisplay(String message, String fileName) { super("Retrieved message from file '"+ fileName+ "' - Steganography."); setDefaultCloseOperation(DISPOSE_ON_CLOSE);

getContentPane().add(new JScrollPane(new JTextArea(message, 14, 50)));

Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); int width= (int)(0.75* d.width); int height= (int)(0.75* d.height); setSize(width, height); setLocation((d.width- width)/2, (d.height- height)/2); setVisible(true); } }

############## Bach End Handler ############


114

import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.crypto.*; import javax.crypto.spec.*;

public class BackEndHandler extends Thread { public static final short EMBED_MESSAGE= public static final short EMBED_FILE= public static final short RETRIEVE_MESSAGE= public static final short RETRIEVE_FILE= 3; public static final short EDIT_MASTER= 4; 0; 1; 2;

private short operation; private WindowAdapter client;

private JFileChooser fileChooser; private MyFileView fileView;

private File masterFile, dataFile, outputFile;

private int result, result2;

public BackEndHandler(WindowAdapter client, short operation) { this.client= client;


115

this.operation= operation;

fileChooser= new JFileChooser("./"); fileChooser.setFileSelectionMode(fileChooser.FILES_ONLY); fileChooser.setDialogType(fileChooser.CUSTOM_DIALOG); fileChooser.setAccessory(new FilePreviewer(fileChooser));

MyFileFilter filter1= new MyFileFilter(new String[]{"bmp", "jpg", "gif", "tif"}, "Picture files"); MyFileFilter filter2= new MyFileFilter(new String[]{"mp3", "wav", "ram", "wma"}, "Audio files"); MyFileFilter filter3= new MyFileFilter(new String[]{"mpg", "wmv", "dat"}, "Video files"); fileChooser.addChoosableFileFilter(filter1); fileChooser.addChoosableFileFilter(filter2); fileChooser.addChoosableFileFilter(filter3); }

public void run() { if(!chooseMasterFile()) return;

if(operation== EMBED_MESSAGE || operation== EMBED_FILE) if(!chooseOutputFile()) return;

if(operation== EMBED_FILE) if(!chooseDataFile()) return;

116

SteganoInformation steg; switch(operation) { case EMBED_MESSAGE: new EmbedMessageGUI(this); break; case EMBED_FILE: new EmbedFileGUI(this); break;

case RETRIEVE_MESSAGE: steg= new SteganoInformation(masterFile); if(steg.isEster()) showEster(steg); else if(!steg.isValid()) JOptionPane.showMessageDialog(null, "File '"+ masterFile.getName()+ "' does not contain any message or file\nembedded using Seganograph 2.0.0 or later!", "Invalid Steganography file!", JOptionPane.WARNING_MESSAGE); else new PreRetrieveGUI(steg, PreRetrieveGUI.RETRIEVE_MESSAGE); break; case RETRIEVE_FILE: steg= new SteganoInformation(masterFile); if(steg.isEster()) showEster(steg); else if(!steg.isValid()) JOptionPane.showMessageDialog(null, "File '"+ masterFile.getName()+

117

"' does not contain any message or file\nembedded using Seganograph 2.0.0 or later!", "Invalid Steganography file!", JOptionPane.WARNING_MESSAGE); else new PreRetrieveGUI(steg, PreRetrieveGUI.RETRIEVE_FILE); } }

public boolean chooseMasterFile() { int result; do { result= fileChooser.showDialog(null, "Select Master file"); if(result== fileChooser.APPROVE_OPTION) { masterFile= fileChooser.getSelectedFile(); if(!checkFileExistency(masterFile)) continue; else break; } } while(result!= fileChooser.CANCEL_OPTION);

if(result== fileChooser.CANCEL_OPTION) return false; else return true; }


118

public boolean chooseOutputFile() { int result; do { File previousFile= fileChooser.getSelectedFile(); result= fileChooser.showDialog(null, "Select Output file"); if(result== fileChooser.APPROVE_OPTION) { outputFile= fileChooser.getSelectedFile(); if(outputFile.exists()) { result2= JOptionPane.showConfirmDialog(null, "File "+ outputFile.getName()+ " already exists!\nWould you like to OVERWRITE it?", "File already exists!", JOptionPane.YES_NO_OPTION); if(result2== JOptionPane.NO_OPTION) { if(previousFile!= null) fileChooser.setSelectedFile(previousFile); continue; } } break; } } while(result!= fileChooser.CANCEL_OPTION);

119

if(result== fileChooser.CANCEL_OPTION) return false; else return true; }

public boolean chooseDataFile() { do { result= fileChooser.showDialog(null, "Select Data file"); if(result== fileChooser.APPROVE_OPTION) { dataFile= fileChooser.getSelectedFile(); if(!checkFileExistency(dataFile)) continue; else break; } } while(result!= fileChooser.CANCEL_OPTION);

if(result== fileChooser.CANCEL_OPTION) return false; else return true; }

public File getMasterFile() public File getOutputFile()

{ return masterFile; } { return outputFile; }


120

public File getDataFile()

{ return dataFile; }

public void setMasterFile(File file) public void setOutputFile(File file) public void setDataFile(File file)

{ masterFile= file; } { outputFile= file; } { dataFile= file; }

private boolean checkFileExistency(File file) { if(!file.exists()) { JOptionPane.showMessageDialog(null, "File "+ file.getName()+ " does not exist!", "Inexistent file!", JOptionPane.ERROR_MESSAGE); return false; }

return true; }

private void showMessage(String message, String title) { JOptionPane.showMessageDialog(null, message, title, JOptionPane.WARNING_MESSAGE); }

private void showEster(SteganoInformation steg) { Object message[]= new Object[3];

121

message[0]= new MyJLabel("This is an encrypted zone.", Color.red, Color.gray); message[1]= new JLabel("Please enter password to continue."); JPasswordField pass= new JPasswordField(10); message[2]= pass;

String options[]= {"Retrieve now", "Cancel"}; int result= JOptionPane.showOptionDialog(null, message, "Encrypted zone" , JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);

if(result== 1) return;

String password= new String(pass.getPassword()); if(password.length()<8) JOptionPane.showMessageDialog(null, "This was not the right password!", "Invalid password", JOptionPane.OK_OPTION); else { int fileSize= (int) steg.getFile().length(); byte[] byteArray= new byte[fileSize]; try { DataInputStream in= new DataInputStream(new FileInputStream(steg.getFile())); in.read(byteArray, 0, fileSize); in.close();

122

Cipher cipher= Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password.substring(0, 8).getBytes(), "DES"));

byteArray= cipher.doFinal(byteArray); } catch(Exception e) { return; }

JFrame frame= new JFrame("Enjoy the ester egg..."); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.getContentPane().add(new JScrollPane(new JLabel(new ImageIcon(byteArray)))); frame.setBackground(Color.white);

Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); frame.setSize(d.width, d.height/2); frame.setVisible(true); } }}

Chapter 6 Testing Software Testing Types:


Black box testing - Internal system design is not considered in this type of testing. Tests are based on requirements and functionality. White box testing - This testing is based on knowledge of the internal logic of an applications code. Also known as Glass box Testing. Internal software and code working should be known for this type of testing. Tests are based on coverage of code statements, branches, paths, conditions.

123

Unit testing - Testing of individual software components or modules. Typically done by the programmer and not by testers, as it requires detailed knowledge of the internal program design and code. may require developing test driver modules or test harnesses. Incremental integration testing - Bottom up approach for testing i.e continuous testing of an application as new functionality is added; Application functionality and modules should be independent enough to test separately. done by programmers or by testers. Integration testing - Testing of integrated modules to verify combined functionality after integration. Modules are typically code modules, individual applications, client and server applications on a network, etc. This type of testing is especially relevant to client/server and distributed systems. Functional testing - This type of testing ignores the internal parts and focus on the output is as per requirement or not. Black-box type testing geared to functional requirements of an application. System testing - Entire system is tested as per the requirements. Black-box type testing that is based on overall requirements specifications, covers all combined parts of a system. End-to-end testing - Similar to system testing, involves testing of a complete application environment in a situation that mimics real-world use, such as interacting with a database, using network communications, or interacting with other hardware, applications, or systems if appropriate. Regression testing - Testing the application as a whole for the modification in any module or functionality. Difficult to cover all the system in regression testing so typically automation tools are used for these testing types. Acceptance testing -Normally this type of testing is done to verify if system meets the customer specified requirements. User or customer do this testing to determine whether to accept application. Load testing - Its a performance testing to check system behavior under load. Testing an application under heavy loads, such as testing of a web site under a range of loads to determine at what point the systems response time degrades or fails. Stress testing - System is stressed beyond its specifications to check how and when it fails. Performed under heavy load like putting large number beyond storage capacity, complex database queries, continuous input to system or database load. Performance testing - Term often used interchangeably with stress and load testing. To check whether system meets performance requirements. Used different performance and load tools to do this. Usability testing - User-friendliness check. Application flow is tested, Can new user understand the application easily, Proper help documented whenever user stuck at any point. Basically system navigation is checked in this testing.
124

Install/uninstall testing - Tested for full, partial, or upgrade install/uninstall processes on different operating systems under different hardware, software environment. Recovery testing - Testing how well a system recovers from crashes, hardware failures, or other catastrophic problems. Security testing - Can system be penetrated by any hacking way. Testing how well the system protects against unauthorized internal or external access. Checked if system, database is safe from external attacks. Compatibility testing - Testing how well software performs in a particular hardware/software/operating system/network environment and different combination s of above. Comparison testing - Comparison of product strengths and weaknesses with previous versions or other similar products. Alpha testing - In house virtual user environment can be created for this type of testing. Testing is done at the end of development. Still minor design changes may be made as a result of such testing. Beta testing - Testing typically done by end-users or others. Final testing before releasing application for commercial purpose.

Chapter 7 Project Plan 5.1 Team Structure


Sachin Kumar Rathi

Designing Solution Strategy Coding

125

Pradeep Kumar Maurya

Designing Presentation Coding

Kamlesh Kumar Maddheshiya Documentation Presentation SRS

Krishn Kanhaiya Agrawal Testing Documentation SRS

5.2 Development Schedule


Table 5.2 Development Schedule

Duration

Tasks Accomplished

1st Week of August,2009

Introduction of project

126

1st Week Of September,2009

System requirement

1st Week Of October,2009

DFD, Use Case-Diagram

2nd Week Of November,2009

System Requirement Specification

2nd Week Of February,2010

Designing

Last Week Of April,2010

First Running Module Of Project

Chapter 8 System Features and Limitations

6.1 Features:
Implementing the system will facilitate the following:

A good design will ensure that the system will continue to work as long as no procedural changes take place. User-friendly interface for the access to the system. The cover file can be executed normally after hiding Operation. As an increasing amount of data is stored on computers & transmitted over network, it is not surprising that stegnography has entered the digital age.
127

Stegnography provides some useful & commercially important functions in digital world.

6.2 Limitations
Some limitations exist with using stegnography though not too complex to overcome. They are: First the sender & receiver must agree on a method in which to hide the message. Otherwise, the receiver may never know they have a message since it is hidden. The really big limitation is that editing or compressing the picture do catastrophic damage to the hidden information. Quite an amount of covering information is needed to hide whatever we want to. At least 8 to 10 times more if we really want it to be non-detectable. Nevertheless if the fact of the hiding becomes evident then the entire business of hiding becomes virtually useless, if the information is not encrypted from before.

6.3 Applications
Image Steganography has many applications, especially in todays modern, hightech world. Privacy and anonymity is a concern for most people on the internet. Some of the applications are: 1. Digital Watermarking: Steganography can be used for, digital watermarking where a message (being simply an identifier) is hidden in an image so that its source can be tracked or verified. 2. Modern Printers: Steganography is used by some modern printers, including HP and Xerox brand color laser printers. Tiny yellow dots are added to each page. The dots are barely visible and contain encoded printer serial numbers, as well as date and time stamps. 3. Tamper proofing: Information hidden may be a signed summary or a hash value which can be used to detect unauthorized modifications.
128

4. Unobtrusive communications: Important on the modern battlefield. Detection of a signal may lead quickly to the sender being attacked. 5. Hacking: It can be used by hackers to send viruses and trojans to compromise machines, and also by terrorists and other organizations that rely on covert operations to communicate secretly and safely. 6. Steganography covers even the existence of any hidden message. 7. It does not increase the size of the covering file for it utilizes its redundancy.

Chapter 9 Snapshots

129

Fig 7.1 Main Form

130

Fig 7.2 Encrypt Form GUI

131

Fig 7.3 Password Validation

132

Fig 7.4 Encrypted Message

133

Chapter 10 Conclusion

We have successfully implemented Steganograhy in text and file. Result are satisfactory and as per expectations. With this project we have learned a lot, especially about bit. We became more interested in the subject the more we researched it. The encryption of the message increases the degree of security of hiding technique which is used in the proposed system. Steganography has its place in security. It is not intended to replace cryptography but supplement it. Hiding a message with steganography methods reduces the chance of a message being detected. However, if that message is also encrypted, if discovered, it must also be cracked (yet another layer of protection). Steganography combined with cryptography becomes a powerful tool for security.

134

CHAPTER 11 References

Books: 1. K.K.Agarwal & Yogesh Singh, Software Engineering (3rd Edition). 2. Pankaj Jalote, An Interrated Approach to Software Engineering Narosa publication house. 3. Roger S. Pressman, Software Engineering. 4. Katzenbeisser, Stefan, & Petitcolas, Fabien, A.P. (Eds.). (2000). Information Hiding Techniques for Steganography and Digital Watermarking Boston, MA: Artech House. 5. Gary C. Kessler, An Overview of Steganography for the Computer Forensics Examiner, 2004.

Websites: 1. Steganography, by Neil F. Johnson, George Mason University,

http://www.jjtc.com/stegdoc/sec202.html 2. How Stego Online Works. http://www.stego.com/howto.html

135

S-ar putea să vă placă și