0

I'm currently running into problems decrypting my data. The base64 of the encoded string is being stored in the database. So, I'm printing out the encoded string and then trying to run it back through with "DECRYPT" instead of "ENCRYPT". However, I never get a value that the Decrypter method likes, it always gives me an error about parameters or the value not being 16 bytes.

public class crypto {
    public static void main(String [] args) {
        String s = args[0];
        String s1 = args[1];
        String ivkey = "thisisasecretkey";
        byte[] ivraw = ivkey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(ivraw, "AES");

        if (s.equalsIgnoreCase("ENCRYPT")) {
            try {
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                byte[] encrypted = cipher.doFinal(s1.getBytes());
                System.out.println(new String(Base64.encodeBase64(encrypted)));

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            try {
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);
                byte[] encrypted = cipher.doFinal(s1.getBytes());
                System.out.println(new String(Base64.decodeBase64(encrypted)));

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return;
    };
}

command:crypto "ENCRYPT" "password"
output: 5eQvSzPG1TE2AybgCmeV6A==

command:crytpo "DECRYPT" "5eQvSzPG1TE2AybgCmeV6A=="
output: java.security.InvalidKeyException: Parameters missing

I'm aware of the security flaws, that's not what I'm asking about and I would prefer answers/comments not get cluttered with best practices.

2 Answers 2

2

You should do base 64 decoding, and you should do that before decrypting.

Sign up to request clarification or add additional context in comments.

Comments

1

You are not including the initialization vector (IV). AES in CBC mode has both a 16 byte IV and the 16 byte symmetric key.

String IV = "AAAAAAAAAAAAAAAA"; // generate this randomly
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(IV.getBytes()));
byte[] encrypted = cipher.doFinal(s.getBytes());

Edit: as it turns out, encryption does not require a IV to be provided (as owlstead pointed out), but decryption does. The best bet would be to be explicit and use IV in both encryption and decryption. Change your decryption function to include the IV, and you will run into the other error in your code that owlstead pointed out.

3 Comments

You should use an IV, but Java - or at least the default Oracle provider in Java - uses a zero-valued IV if it is not specified explicitly.
I am using OpenJDK and if I do not specify the IV i get the same error as OP.
My bad too, it seems both issues could lead to exceptions, voted up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.