Conner Dassen
Conner Dassen

Reputation: 740

How can I read an encrypted text from a file and decrypt it?

I have some account info that is being encrypted and written to a file like this:

//imports here
public class Main 

    public static void main(String[] args) {


        try {
            String text = "this text will be encrypted";

            String key = "Bar12345Bar12345";

            //Create key and cipher
            Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");

            //encrypt text
            cipher.init(Cipher.ENCRYPT_MODE, aesKey);
            byte[] encrypted = cipher.doFinal(text.getBytes());
            write(new String(encrypted));

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }

    }

    public static void write(String message) {
        BufferedWriter bw = null;
        FileWriter fw = null;

        try {

            String data = message;

            File file = new File(FILENAME);
            if (!file.exists()) {
                file.createNewFile();
            }


            fw = new FileWriter(file.getAbsoluteFile(), true);
            bw = new BufferedWriter(fw);

            bw.write(data);

        } catch (IOException e) {

            e.printStackTrace();

        } finally {

            try {

                if (bw != null)
                    bw.close();

                if (fw != null)
                    fw.close();

            } catch (IOException ex) {

                ex.printStackTrace();

            }
        }
    }

}

So the contents of the file is one string without any breaks in between. If I wanted to decrypt the string, I would do this:

String key = "Bar12345Bar12345";
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
byte[] encrypted = text.getBytes(); 
cipher.init(Cipher.DECRYPT_MODE, aesKey);
String decrypted = new String(cipher.doFinal(encrypted));
System.err.println(decrypted);

This works fine as long as byte[] encrypted is the same as used as in the encrypting process, but when I try to read the encrypted text from the file using a FileReader and a BufferedReader and change it into a byte using lines.getByte() it throws the exception

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

Upvotes: 0

Views: 2774

Answers (2)

Maarten Bodewes
Maarten Bodewes

Reputation: 94028

You are trying to treat your encrypted array contents as (platform encoded) text, while it is not - it consists of random bytes.

You either need to create a binary file by writing the contents of encrypted to it directly. That or you can create a text file by first encoding encrypted to base64.

Currently you are trying to read lines, but there aren't any. And if there are some line endings in there they will be stripped from the ciphertext before those bytes can be decrypted.

If you perform new String(encrypted) then it is also possible that you lose part of your data, as unsupported encodings are removed from the string without warning.


Note that the word "ciphertext" is a bit misleading; modern ciphers such as AES handle binary data, not text.

Upvotes: 1

user52472
user52472

Reputation: 111

Compare the cipher text from the encrypting process with the cipher text from lines.getByte() before you try to do any decryption. They are most likely different. Try reading the entire file into a byte[] first before decrypting it. Symmetric ciphers need to do their work on blocks of the same size, in this case 16 bytes.

I would also be remiss if I didn't comment on some of the poor protocol choices.

  1. Hard coded key - Your encryption key should never be hard-coded in your application. If you ever need to change your encryption key, you are not able to do so. If your application is distributed to end users, it's easy for them to recover the key using an application like strings.
  2. You are using ECB as your mode of operation. ECB has several ways it can be attacked, such as block shuffling, which can allow an attacker to decrypt data without having the encryption key.

Encryption is hard to get right on your own. Consider solving your problem a different way.

Upvotes: 1

Related Questions