com.daioware.picture.security.Steganography Maven / Gradle / Ivy
The newest version!
package com.daioware.picture.security;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.daioware.security.AesEncrypter;
/*
*Class Steganography
*/
public class Steganography{
private AesEncrypter cipher;
private String key;
public Steganography(String key) {
setKey(key);
cipher=new AesEncrypter();
}
/*
*Encrypt an image with text, the output file will be of type .png
*@param path The path (folder) containing the image to modify
*@param original The name of the image to modify
*@param ext1 The extension type of the image to modify (jpg, png)
*@param stegan The output name of the file
*@param message The text to hide in the image
*@param type integer representing either basic or advanced encoding
*/
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public boolean encode(String path, String original, String ext1, String stegan, String message) throws IOException
{
String file_name = image_path(path,original,ext1);
BufferedImage image_orig = getImage(file_name);
//user space is not necessary for Encrypting
BufferedImage image = user_space(image_orig);
image = add_text(image,message);
return(setImage(image,new File(image_path(path,stegan,"png")),"png"));
}
public boolean encodeImage(String path, String original, String ext1, String stegan,
byte[] bytes) throws IOException
{
String file_name = image_path(path,original,ext1);
BufferedImage image_orig = getImage(file_name);
//user space is not necessary for Encrypting
BufferedImage image = user_space(image_orig);
image = add_image(image,bytes);
return(setImage(image,new File(image_path(path,stegan,"png")),"png"));
}
/*
*Decrypt assumes the image being used is of type .png, extracts the hidden text from an image
*@param path The path (folder) containing the image to extract the message from
*@param name The name of the image to extract the message from
*@param type integer representing either basic or advanced encoding
*/
public String decode(String path, String name) throws IOException {
byte[] decode;
//user space is necessary for decrypting
BufferedImage image = user_space(getImage(image_path(path,name,"png")));
decode = decode_text(get_byte_data(image));
return(new String(cipher.decrypt(getKey(),decode)));
}
/*
*Returns the complete path of a file, in the form: path\name.ext
*@param path The path (folder) of the file
*@param name The name of the file
*@param ext The extension of the file
*@return A String representing the complete path of a file
*/
private String image_path(String path, String name, String ext){
return path + File.separator + name + "." + ext;
}
/*
*Get method to return an image file
*@param f The complete path name of the image.
*@return A BufferedImage of the supplied file path
*@see Steganography.image_path
*/
private BufferedImage getImage(String f) throws IOException{
BufferedImage image = null;
File file = new File(f);
image = ImageIO.read(file);
return image;
}
/*
*Set method to save an image file
*@param image The image file to save
*@param file File to save the image to
*@param ext The extension and thus format of the file to be saved
*@return Returns true if the save is succesful
*/
private boolean setImage(BufferedImage image, File file, String ext) throws IOException{
file.delete(); //delete resources used by the File
ImageIO.write(image,ext,file);
return true;
}
public byte[] decodeImage(String path, String name) throws IOException{
byte[] decode;
//user space is necessary for decrypting
BufferedImage image = user_space(getImage(image_path(path,name,"png")));
decode = decode_text(get_byte_data(image));
return cipher.decrypt(getKey(),decode);
}
/*
*Handles the addition of text into an image
*@param image The image to add hidden text to
*@param text The text to hide in the image
*@return Returns the image with the text embedded in it
*/
private BufferedImage add_image(BufferedImage image, byte[] msg){
//convert all items to byte arrays: image, message, message length
byte img[] = get_byte_data(image);
msg = cipher.encrypt(getKey(),msg);
byte len[] = bit_conversion(msg.length);
encode_text(img, len, 0); //0 first positiong
encode_text(img, msg, 32); //4 bytes of space for length: 4bytes*8bit = 32 bits
return image;
}
private BufferedImage add_text(BufferedImage image, String text) {
//convert all items to byte arrays: image, message, message length
byte img[] = get_byte_data(image);
byte msg[] = cipher.encrypt(getKey(),text);
byte len[] = bit_conversion(msg.length);
encode_text(img, len, 0); //0 first positiong
encode_text(img, msg, 32); //4 bytes of space for length: 4bytes*8bit = 32 bits
return image;
}
/*
*Creates a user space version of a Buffered Image, for editing and saving bytes
*@param image The image to put into user space, removes compression interferences
*@return The user space version of the supplied image
*/
private BufferedImage user_space(BufferedImage image){
//create new_img with the attributes of image
BufferedImage new_img = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D graphics = new_img.createGraphics();
graphics.drawRenderedImage(image, null);
graphics.dispose(); //release all allocated memory for this image
return new_img;
}
/*
*Gets the byte array of an image
*@param image The image to get byte data from
*@return Returns the byte array of the image supplied
*@see Raster
*@see WritableRaster
*@see DataBufferByte
*/
private byte[] get_byte_data(BufferedImage image) {
WritableRaster raster = image.getRaster();
DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
return buffer.getData();
}
/*
*Gernerates proper byte format of an integer
*@param i The integer to convert
*@return Returns a byte[4] array converting the supplied integer into bytes
*/
private byte[] bit_conversion(int i)
{
//originally integers (ints) cast into bytes
//byte byte7 = (byte)((i & 0xFF00000000000000L) >>> 56);
//byte byte6 = (byte)((i & 0x00FF000000000000L) >>> 48);
//byte byte5 = (byte)((i & 0x0000FF0000000000L) >>> 40);
//byte byte4 = (byte)((i & 0x000000FF00000000L) >>> 32);
//only using 4 bytes
byte byte3 = (byte)((i & 0xFF000000) >>> 24); //0
byte byte2 = (byte)((i & 0x00FF0000) >>> 16); //0
byte byte1 = (byte)((i & 0x0000FF00) >>> 8 ); //0
byte byte0 = (byte)((i & 0x000000FF) );
//{0,0,0,byte0} is equivalent, since all shifts >=8 will be 0
return(new byte[]{byte3,byte2,byte1,byte0});
}
/*
*Encode an array of bytes into another array of bytes at a supplied offset
*@param image Array of data representing an image
*@param addition Array of data to add to the supplied image data array
*@param offset The offset into the image array to add the addition data
*@return Returns data Array of merged image and addition data
*/
private byte[] encode_text(byte[] image, byte[] addition, int offset)
{
//check that the data + offset will fit in the image
if(addition.length + offset > image.length)
{
throw new IllegalArgumentException("File not long enough!");
}
//loop through each addition byte
for(int i=0; i=0; --bit, ++offset) //ensure the new offset value carries on through both loops
{
//assign an integer to b, shifted by bit spaces AND 1
//a single bit of the current byte
int b = (add >>> bit) & 1;
//assign the bit by taking: [(previous byte value) AND 0xfe] OR bit to add
//changes the last bit of the byte in the image to be the bit of addition
image[offset] = (byte)((image[offset] & 0xFE) | b );
}
}
return image;
}
/*
*Retrieves hidden text from an image
*@param image Array of data, representing an image
*@return Array of data which contains the hidden text
*/
private byte[] decode_text(byte[] image)
{
int length = 0;
int offset = 32;
//loop through 32 bytes of data to determine text length
for(int i=0; i<32; ++i) //i=24 will also work, as only the 4th byte contains real data
{
length = (length << 1) | (image[i] & 1);
}
byte[] result = new byte[length];
//loop through each byte of text
for(int b=0; b
© 2015 - 2024 Weber Informatics LLC | Privacy Policy