Encrypting and decrypting a file using CipherInputStream and CipherOutputStream

20.4k views Asked by At

I've been trying to write an encrypted file in AES and decrypt it subsequently by using Cipher Streams provided in JCA. However, I'm having problems while reading the file, as the decryption is going haywire.

public class CipherStreams {
public static void main(String[] args) {
    try {
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        Key k = keygen.generateKey();

        Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
        aes.init(Cipher.ENCRYPT_MODE, k);
        FileOutputStream fs = new FileOutputStream("Encrypyed.txt");
        CipherOutputStream out = new CipherOutputStream(fs, aes);
        out.write("[Hello:Okay]\nOkay".getBytes());
        out.close();

        Cipher aes2 = Cipher.getInstance("AES/ECB/PKCS5Padding");
        aes2.init(Cipher.DECRYPT_MODE, k);

        FileInputStream fis = new FileInputStream("Encrypyed.txt");
        CipherInputStream in = new CipherInputStream(fis,aes2);
        byte[] b = new byte[8];
        int i = in.read(b);
        while(i!=-1) {
            System.out.print((char)i);
            i = in.read(b);
        }
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IOException ex) {
        Logger.getLogger(CipherStreams.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

I'm receiving a single byte output as 5. Can anyone please help point out the problem?

1

There are 1 answers

2
JB Nizet On BEST ANSWER

You're not writing the bytes read, you're writing the number of bytes being read.

You're also assuming that the default platform encoding just transforms each character to a byte.

Just do the reverse of what you did when writing: read everything, and transform the read byte array to a String, then print that string:

public class CipherStreams {
    public static void main(String[] args) {
        try {
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            Key k = keygen.generateKey();

            Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
            aes.init(Cipher.ENCRYPT_MODE, k);
            String fileName = "Encrypted.txt";
            FileOutputStream fs = new FileOutputStream(fileName);
            CipherOutputStream out = new CipherOutputStream(fs, aes);
            out.write("[Hello:Okay]\nOkay".getBytes());
            out.flush();
            out.close();

            Cipher aes2 = Cipher.getInstance("AES/ECB/PKCS5Padding");
            aes2.init(Cipher.DECRYPT_MODE, k);

            FileInputStream fis = new FileInputStream(fileName);
            CipherInputStream in = new CipherInputStream(fis, aes2);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            byte[] b = new byte[1024];
            int numberOfBytedRead;
            while ((numberOfBytedRead = in.read(b)) >= 0) {
                baos.write(b, 0, numberOfBytedRead);
            }
            System.out.println(new String(baos.toByteArray()));
        }
        catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IOException ex) {
            ex.printStackTrace();
            ;
        }
    }
}