0

I am doing an image Steganography project and I am implementing RSA cryptography to make the hidden message more secure.

I am using the BigInteger class, and the RSA on its own is ok, but when used after the encrypted text has been extracted from the cover image it is inconsistent in decrypting the cipher text.

RSA key = new RSA(1024);
BigInteger[] privateKey = key.getPrivKey();
String s = "Hello World";
        byte[] bytes = s.getBytes();
        BigInteger message = new BigInteger(bytes);

        BigInteger encrypt = key.encrypt(message);

        Stego steg = new Stego();
        steg.encode(ImageIO.read(new File("horse_PNG2538.png")), encrypt.toString(), "stegTest");

String toDecrypt = steg.decode(ImageIO.read(new File("stegTest.png")));
BigInteger messageD = new BigInteger(toDecrypt);

BigInteger decrypt = key.decrypt(messageD, privateKey);
String plainText = new String(decrypt.toByteArray());

Encode takes in its parametes a BufferedImage, String (text to be hidden in the image) and the name of the output image.

Decode takes an image and extracts the hidden text and returns a String.

I have compared the toString() of both messageD (the cipherText extracted from the image) and encrypt, both should be the same all the time but on some runs their output differs giving the wrong plainText when decrypted.

How can I make this consistent?

Edit additional code: this is how I am embedding text into an image in Stego class;

    public static BufferedImage encode(BufferedImage coverImage, String text, String newFileName) {
    //create userSpace
    BufferedImage userSpace = user_space(coverImage);
    return embedText(userSpace, text, newFileName);
}//END OF ENCODE

public static BufferedImage embedText(BufferedImage image, String text, String name) {
    int bitMask = 0x00000001;   
    int currentChar;               
    int x = 0;              
    int y = 0;

    String toEmbed = "***" + text.length() + "***" + text;
    byte[] msg = toEmbed.getBytes(); 
    System.out.println("" + toEmbed.length());

    for (int i = 0; i < msg.length; i++) {
        currentChar = msg[i];       
        for (int j = 0; j < 8; j++) { //0-7 bits

             int flag = currentChar & bitMask;   // get 1 digit from the current character

            if (x < image.getWidth()) {
                image.setRGB(x, y, image.getRGB(x, y)& 0xFE | flag);    
                x++;
            } else {
                x = 0; 
                y++;
                image.setRGB(x, y, image.getRGB(x, y)&0xFE | flag);    
            }

            currentChar = currentChar >> 1;             // get the next digit from the character
        }
    }


    try {
        File outputfile = new File(name + ".png");
        ImageIO.write(image, "png", outputfile);
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Something went wrong with creating the new image");
    }
    return image;
} 

and How I extract text;

public static String decode(BufferedImage image) {
    Object[] details = isEncrypted(image);
    int length = 0;
    String secretMessage = "";
    if ((boolean) details[0] == false) {
        System.out.println("Not Encrypted");
        return "nothing";
    }

    length = (int) details[1];

    char[] temp = extractText(image, length);
    for(int i = 0; i<temp.length; i++){
        secretMessage += (new StringBuilder().append(temp[i])).toString();
    }

    return secretMessage.substring((int)details[2]);
}

public static char[] extractText(BufferedImage image, int length) {

    int bitMask = 0x00000001;   
    int x = 0;                  
    int y = 0;                  
    int flag;
    char[] c = new char[length];    

    for (int i = 0; i < length; i++) {
        int bit = 0;


        for (int j = 0; j < 8; j++) {
            if (x < image.getWidth()) {
                flag = image.getRGB(x, y) & bitMask;   
                x++;
            } else {
                x = 0;
                y++;
                flag = image.getRGB(x, y) & bitMask;    
            }


            if (flag == 1) {
                bit = bit >> 1;
                bit = bit | 0x80;
            } else {
                bit = bit >> 1;
            }
        }
        c[i] = (char) bit;  


    }
    return c;
}
Null
  • 9
  • 3
  • Then obviously the `Stego` class is the culprit. Where does it come from? It doesn't look like a standard class. Note that posting the whole code for the `Stego` class would not be advisable if the code is extensive. – Artjom B. Mar 12 '17 at 17:04
  • @ArtjomB. I have added some code from Stego to give more context, thanks! – Null Mar 12 '17 at 17:24
  • There is the `decode` method missing. Have you tested the `Stego` class separately? – Artjom B. Mar 12 '17 at 17:41
  • @ArtjomB. I have tested it seperately and it works fine, succesfully returning the text that was initially embedded. I have added `decode` now. Looking at my code again I think the problem is coming from when `encrypt` is being embedded in the image, it sometimes gets altered. – Null Mar 12 '17 at 18:04
  • Are you sure that the image is big enough for the RSA ciphertext to be embedded? – Artjom B. Mar 12 '17 at 18:33
  • Unless you provide us with an image and text, for which the process doesn't work, we can't replicate your problem. – Reti43 Mar 12 '17 at 19:00
  • @Reti43 the text is there as `String s = "Hello World";` in the first block of code, the image used is this [link](http://pngimg.com/uploads/horse/horse_PNG2538.png) – Null Mar 12 '17 at 19:08

0 Answers0