0

I have to embed text in an encrypted image(Stegnography). I googled and found codes for embedding text in an image. But I have to encrypt image at first and embed text in this encrypted image. My tries are as follows.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tbn;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.imageio.ImageIO;

/**
 *
 * @author user
 */
public class DbtClass {

    public static void main(String[] args) {
        try {
            BufferedImage orgnlimage = ImageIO.read(new File("parrruuuuu.png"));
            orgnlimage = user_space(orgnlimage);
            byte[] orgnlimagebytes = get_byte_data(orgnlimage);
            byte[] encryptedbytes = encrypt(orgnlimagebytes, "abc");
            BufferedImage encryptedimage = toImage(encryptedbytes, orgnlimage.getWidth(), orgnlimage.getHeight());
            ImageIO.write(encryptedimage, "png", new File("encrypted.png"));

            /////////////////////////////////////////////////////////////////////
            /////////////////////////////////////////////////////////////////////

            byte[] encryptedbytes2 = get_byte_data(encryptedimage);
            System.out.println("encryptedbytes before writing: "+encryptedbytes2.length);

            BufferedImage encryptedimage3 = ImageIO.read(new File("encrypted.png"));
            byte[] encryptedbyte3 = get_byte_data(encryptedimage3);
            System.out.println("encryptedbytes after writing: "+encryptedbyte3.length);


        } catch (IOException ex) {
            Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static 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;
    }

    public static byte[] get_byte_data(BufferedImage image) {
        WritableRaster raster = image.getRaster();
        DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
        return buffer.getData();
    }

    public static byte[] encrypt(byte[] orgnlbytes, String key) {
        byte[] encbytes = null;
        try {
            Cipher cipher = Cipher.getInstance("AES");
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            // cryptograph. secure random 
            random.setSeed(key.getBytes());

            keyGen.init(128, random);
            // for example
            SecretKey secretKey = keyGen.generateKey();
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            encbytes = cipher.doFinal(orgnlbytes);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BadPaddingException ex) {
            Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex);
        }
        return encbytes;
    }

    public static BufferedImage toImage(byte[] imagebytes, int width, int height) {
        DataBuffer buffer = new DataBufferByte(imagebytes, imagebytes.length);
        WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, 3 * width, 3, new int[]{2, 1, 0}, (Point) null);
        ColorModel cm = new ComponentColorModel(ColorModel.getRGBdefault().getColorSpace(), false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
        return new BufferedImage(cm, raster, true, null);
    }
}

Here I was written the encrypted image using raster class and ImageIO.write().Then read this encrypted bytes from file Using ImageIO.read().The encrypted byte[] before writing the image and the byte[] after reading the image are totaly different

TBN
  • 45
  • 9
  • But before writing image to file,from BufferedImage I got extra 16 bytes that you have mentioned. So I think the problem might be in ImageIO.write() or in ImageIO.read() anyway thankyou for your comment @Reti43 – TBN Feb 07 '15 at 17:31
  • "Steganography is the art or practice of concealing a file, message, image, or video within another file, message, image, or video." If you think you need to encrypt the image to perform Steganography then you're completely off route. – Maarten Bodewes Feb 07 '15 at 17:41
  • Did you first embed the message in the carrier and then encrypted the carrier? Why would you even encrypt the carrier image? And what do you mean by "*image can't be identified from bytes*"? – Reti43 Feb 07 '15 at 18:22
  • The encrypted image bytes before writing and the bytes after reading are not the same.@Reti43 – TBN Feb 07 '15 at 18:31

1 Answers1

1

So here's what happens. Assume an original image of size WxH. Since you have 3 bytes per pixel, your image, orgnlimagebytes, has S = 3*W*H bytes.

Now you encrypt this image with AES, which results in a fixed block size of 16 bytes. If S is not divisible by 16, it will be padded to be so. If it is divisible by 16, another block of 16 bytes will be added. The point here is that the encrypted byte array, encryptedbytes, has a bigger size than orgnlimagebytes. Call this S'.

Now you use the method toImage to create a BufferedImage out of this byte array. You create a buffer of encryptedbytes, turn that to a raster and blah, blah, blah. You do end up with an image of size WxH. What happens, however, is that the BufferedImage object has a reference to the buffer which has S' elements. You only use the first S elements to construct the pixels of the image, but you can still access the rest of the elements from the buffer. So when you turn the BufferedImage to a byte array again, encryptedbytes2, you get all S' number of elements back.

The image only has WxH RGB pixels, so if you try to save that to an image file, that's all you're going to save. You won't save any of the additional bytes from the buffer reference. So when you save and load the image and convert that to a byte array, expectedbytes3, you get the expected number of bytes, which should be S.


This explains the unexpected inconsistency of the encrypted byte array before and after saving to a file. However, aside of the method of encryption, why do you even encrypt the cover image? It would make sense if you encrypted the message before hiding it in the image for extra security in case someone managed to both detect and extract the message. Encrypting the pixel values of the cover image means drastically changing them, which introduces apparent changes.

Community
  • 1
  • 1
Reti43
  • 9,656
  • 3
  • 28
  • 44
  • http://stackoverflow.com/questions/28396404/save-encrypted-image-bytes-to-file-and-recover-to-original-image-in-java – TBN Feb 08 '15 at 16:54
  • The paper is very hard to understand due to poor quality of written language, but at no point does it speak about AES encryption. – Reti43 Feb 08 '15 at 17:05