Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.image.BufferedImage;
- import java.awt.image.DataBufferByte;
- import java.awt.image.WritableRaster;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileReader;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Random;
- import javax.imageio.ImageIO;
- import org.jasypt.util.binary.BasicBinaryEncryptor;
- public class Steg {
- // required no of bytes (image) to store one byte of text
- private static final int DATA_SIZE = 8;
- // INTEGER IS 4 Bytes.
- private static final int MAX_INT_LEN = 4;
- //Password Length
- private static final int PASSWORD_LEN = 10;
- //random password
- private static Random rand = new Random();
- public static boolean hide(String path, String imagePath)
- {
- //Read the message as Byte Array.
- byte[] messageBytes=readMessageBytes(path);
- if(messageBytes==null)
- return false;
- //Generate Password
- String password=generatePassword();
- byte[] passwordBytes=password.getBytes();
- //Encrypt Message
- byte[] encryptedMessageBytes=encryptMessageBytes(messageBytes,password);
- if(encryptedMessageBytes==null)
- return false;
- byte[] inputBytes = buildeStego(passwordBytes,encryptedMessageBytes);
- // read image
- BufferedImage im = loadImage(imagePath);
- // check if the image file is empty
- if (im == null)
- return false;
- // convert the image to Bytes array
- byte imageBytes[] = accessBytes(im);
- if (!singleHide(imageBytes, inputBytes))
- return false;
- System.out.println("HERE2");
- // The new Image
- // String newImage=getFileName(imagePath);
- // return the new image and save it
- System.out.println("HERE AGAIN");
- return writeImageToFile("Msg.png", im);
- }
- private static byte[] readMessageBytes(String path)
- {
- // TODO Auto-generated method stub
- BufferedReader br = null;
- StringBuilder message = new StringBuilder();
- try {
- String sCurrentLine;
- br = new BufferedReader(new FileReader(path));
- while ((sCurrentLine = br.readLine()) != null) {
- message.append(sCurrentLine);
- }
- }
- catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (br != null)
- br.close();
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- byte[] messageBytes=message.toString().getBytes();
- return messageBytes;
- }
- private static byte[] encryptMessageBytes(byte[] messageBytes,
- String password) {
- //USE AES AND MD5 FOR ENCRYPTION
- BasicBinaryEncryptor temp=new BasicBinaryEncryptor();
- temp.setPassword(password);
- return temp.encrypt(messageBytes);
- }
- private static String generatePassword()
- {
- // LETTERS USED IN PASSWORD.
- String letters="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- StringBuffer pass=new StringBuffer(PASSWORD_LEN);
- int index=0;
- for(int i=0;i<PASSWORD_LEN;i++)
- {
- //get random integer
- index=rand.nextInt(letters.length());
- pass.append(letters.charAt(index));
- }
- return pass.toString();
- }
- private static boolean singleHide(byte[] imageBytes, byte[] inputBytes) {
- int imageLength = imageBytes.length;
- System.out.println("Byte length of image: " + imageLength);
- int totalLength = inputBytes.length;
- System.out.println("Total byte length of message: " + totalLength);
- // check if the message can be hidden in the image.
- // EACH BYTE(MESSAGE) REQUIRE 8 BYTES FROM IMAGE.
- if ((totalLength * DATA_SIZE) > imageLength) {
- System.out.println("Image not big enough for message");
- return false;
- }
- hideText(imageBytes, inputBytes, 0);
- return true;
- }
- private static void hideText(byte[] imageBytes, byte[] inputBytes, int index) {
- for (int i = 0; i < inputBytes.length; i++) {
- int value = inputBytes[i];
- // loop through the bits of this byte
- for (int j = 7; j >= 0; j--) {
- // Right shift to get the specific bit
- int bitValue = (value >>> j) & 1;
- // change the last bit for the image byte
- /*
- * The bitwise-AND operation with the hexadecimal FE (1111110
- * binary) clears the right-most bit of imBytes[offset](i.e. the
- * LSB), and the bitwise-OR places the stego bit value into the
- * empty space
- */
- imageBytes[index] = (byte) ((imageBytes[index] & 0xFE) | bitValue);
- index++;
- }
- }
- }
- private static boolean writeImageToFile(String imagePath, BufferedImage im) {
- System.out.println("HERE");
- BufferedImage image = null;
- try {
- image = im;
- ImageIO.write(image, "png", new File(
- "/home/yaramohamed1/workspace/Steganography2/image.png"));
- } catch (IOException e) {
- e.printStackTrace();
- }
- return true;
- }
- // Access the image pixels as byte array to be in the same form of message.
- private static byte[] accessBytes(BufferedImage im) {
- /*
- * Buffered image is made of 3 data structures (Color Space,Sample
- * Model,and Data Buffer) Raster class contains (Sample Model,Data
- * Buffer) Raster Class will manages the the image data,the buffer data
- * will contain the pixel data SampleModel==>Pixel Values
- * ColorModel==>color for the pixels We can access raster class through
- * writableRaster
- */
- WritableRaster raster = im.getRaster();
- DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
- return buffer.getData();
- }
- // Read the image from a file.
- private static BufferedImage loadImage(String imagePath) {
- BufferedImage img = null;
- try {
- img = ImageIO.read(new File(imagePath));
- } catch (IOException e) {
- }
- return img;
- }
- private static byte[] buildeStego(byte[] passwordBytes,byte[] encryptedMessageBytes)
- {
- // From Integer to Bytes array ,because we need to store the length of
- // the messages in bytes too.
- byte[] lengthOfBytes = intToBytes(encryptedMessageBytes.length);
- // Total length of the message+lengthOfIt+lengthOfPassword
- int totalLength = passwordBytes.length+lengthOfBytes.length + encryptedMessageBytes.length;
- byte[] result = new byte[totalLength];
- // create new byte array which contain the bytes array and the length of
- // it.
- int destPosition=0;
- // copy first the byte array of the length
- // (input,startIndex,output,startIndexOfOutput,length of input)
- System.arraycopy(passwordBytes, 0, result,destPosition, passwordBytes.length);
- destPosition+=passwordBytes.length;
- System.arraycopy(lengthOfBytes, 0, result, destPosition, lengthOfBytes.length);
- destPosition+=lengthOfBytes.length;
- // Start copying the messageBytes too
- System.arraycopy(encryptedMessageBytes, 0, result,destPosition,encryptedMessageBytes.length);
- // RESULT===[LengthOfBytes,messageBytes]
- return result;
- }
- // convert from integer to bytes
- private static byte[] intToBytes(int i) {
- // take in consideration that the Integer is 4 bytes.
- // map the parts of the integer to a byte array
- byte[] integerBs = new byte[MAX_INT_LEN];
- integerBs[0] = (byte) ((i >>> 24) & 0xFF);
- integerBs[1] = (byte) ((i >>> 16) & 0xFF);
- integerBs[2] = (byte) ((i >>> 8) & 0xFF);
- integerBs[3] = (byte) (i & 0xFF);
- return integerBs;
- } // e
- // Read Text from file.
- private static String readTextFile(String path) {
- BufferedReader br = null;
- StringBuilder message = new StringBuilder();
- try {
- String sCurrentLine;
- br = new BufferedReader(new FileReader(path));
- while ((sCurrentLine = br.readLine()) != null) {
- message.append(sCurrentLine);
- }
- }
- catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (br != null)
- br.close();
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- return message.toString();
- }
- public static boolean reveal(String imagePath) {
- // load image from file.
- BufferedImage im = loadImage(imagePath);
- // check if the image is empty
- if (im == null)
- return false;
- // get image Bytes
- byte[] imageBytes = accessBytes(im);
- int imageLength=imageBytes.length;
- System.out.println("Byte length of image: " + imageBytes.length);
- String message=extractMessage(imageBytes,0);
- if(message!=null)
- {
- return writeTextToFile("Result.txt", message);
- }
- else
- {
- System.out.println("ERROR : NO MESSAGE");
- return false;
- }
- }
- private static String extractMessage(byte[] imageBytes, int index) {
- String password=getPassword(imageBytes,index);
- if(password==null)
- return null;
- //Move to the length of the message.
- index+=(PASSWORD_LEN*DATA_SIZE);
- int messageLength=getMessageLength(imageBytes,index);
- if(messageLength==-1)
- return null;
- //Move to the message
- index+=(MAX_INT_LEN*DATA_SIZE);
- return getMessage(imageBytes,messageLength,password,index);
- }
- private static String getPassword(byte[] imageBytes, int index) {
- byte[] passwordBytes=extractHiddenBytes(imageBytes,PASSWORD_LEN,index);
- if(passwordBytes==null)
- return null;
- String password=new String(passwordBytes);
- return password;
- }
- private static boolean writeTextToFile(String path, String msg) {
- try {
- File file = new File(
- "/home/yaramohamed1/workspace/Steganography2/result.txt");
- // if file doesnt exists, then create it
- if (!file.exists()) {
- file.createNewFile();
- }
- FileWriter fw = new FileWriter(file.getAbsoluteFile());
- BufferedWriter bw = new BufferedWriter(fw);
- bw.write(msg);
- bw.newLine();
- bw.close();
- System.out.println("Done");
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
- private static String getMessage(byte[] imageBytes, int messageLength,
- String password,int index) {
- byte[] messageBytes = extractHiddenBytes(imageBytes, messageLength,
- index);
- if (messageBytes == null)
- return null;
- BasicBinaryEncryptor temp=new BasicBinaryEncryptor();
- temp.setPassword(password);
- byte[] messagesBytes=null;
- try
- {
- messagesBytes=temp.decrypt(messageBytes);
- }
- catch(Exception e)
- {
- System.out.println("ERROR : DECRYPTION");
- return null;
- }
- String message = new String(messagesBytes);
- return message;
- }
- private static int getMessageLength(byte[] imageBytes, int index) {
- // get the binary message length as byte array
- byte[] lengthBytes = extractHiddenBytes(imageBytes, MAX_INT_LEN, index);
- // check if it is null ,return -1
- if (lengthBytes == null)
- return -1;
- // convert the byte array into an integer
- int messageLength = ((lengthBytes[0] & 0xff) << 24)
- | ((lengthBytes[1] & 0xff) << 16)
- | ((lengthBytes[2] & 0xff) << 8) | (lengthBytes[3] & 0xff);
- // check if messageLength is zero or that the message length is more
- // than the image length
- if (messageLength <= 0 || (messageLength > imageBytes.length)) {
- System.out.println("ERROR : MESSGAE LENGTH");
- return -1;
- }
- return messageLength;
- }
- private static byte[] extractHiddenBytes(byte[] imageBytes, int size,
- int index) {
- // Given that each byte of the message is stored in 8 bytes of the image
- // size==4;
- // datasize=8;
- // check if the image has enough place to retiveral the text from it
- int position = index + (size * DATA_SIZE);
- if (position > imageBytes.length) {
- System.out.println("ERROR : END OF IMAGE");
- return null;
- }
- // Handle the text message in bytes.
- byte[] hiddenBytes = new byte[size];
- for (int j = 0; j < size; j++) {
- // construct new hiddenByte[] each time.
- for (int i = 0; i < DATA_SIZE; i++) {
- // make one hidden byte from DATA_SIZE image bytes
- // the extracted bit will be added to the right end og the
- // hiddenBytes[] with bitwise OR
- hiddenBytes[j] = (byte) ((hiddenBytes[j] << 1) | (imageBytes[index] & 1));
- /*
- * shift existing bits left; store LSB of image byte on the
- * right
- */
- index++;
- }
- }
- return hiddenBytes;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement