juliocb92
juliocb92

Reputation: 96

JAVA: how to encrypt and view an image

I have to cipher an image using Java. I encrypt the image properly but I don't know how to visualize it because when I try to open the file the system tells me that the image is too long or is a corrupt file. How can I do to work with the pic body and without the metadata?

Thanks!!

    // Scanner to read the user's password. The Java cryptography
    // architecture points out that strong passwords in strings is a
    // bad idea, but we'll let it go for this assignment.
    Scanner scanner = new Scanner(System.in);
    // Arbitrary salt data, used to make guessing attacks against the
    // password more difficult to pull off.
    byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
            (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };

    {
        File inputFile = new File("C:/Users/Julio/Documents/charmander.png");
        BufferedImage input = ImageIO.read(inputFile);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeyFactory keyFac = SecretKeyFactory
                .getInstance("PBEWithMD5AndDES");
        // Get a password from the user.
        System.out.print("Password: ");
        System.out.flush();
        PBEKeySpec pbeKeySpec = new PBEKeySpec(scanner.nextLine()
                .toCharArray());
        // Set up other parameters to be used by the password-based
        // encryption.
        PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20);
        SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
        // Make a PBE Cyhper object and initialize it to encrypt using
        // the given password.
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
        pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
        FileOutputStream output = new FileOutputStream(
                "C:/Users/Julio/Documents/imgen.png");
        CipherOutputStream cos = new CipherOutputStream(output, pbeCipher);
        // File outputFile = new File("image.png");
        ImageIO.write(input, "PNG", cos);
        cos.close();

    }
}

Upvotes: 0

Views: 4458

Answers (1)

Durandal
Durandal

Reputation: 20069

You are encrypting the entire output file. Of course the encrypted form isn't a reconizable image file type; if it were encryption would be a little pointless.

What you seem to want is to encrypt the image data, but write it as valid image; the image would then appear to show just random pixels. In principle this isn't much more complicated, just apply the encryption to the pixels in the image you have read, then write that image normally.

In practice it isn't as simple because cyphers are designed to work with streams, while images have an API suited for graphics processing; and to make things more complicated there are different representations internally used to represent different types of images.

So you need to write some glue code to translate in between; getting pixels from the image (e.g. using getRGB(x, y) method), decompose the pixel data into bytes; feed that into the cypher; and transform the encrypted data back into pixels (e.g. using setRGB(x, y, rgb)).

Upvotes: 1

Related Questions