3

this one is very strange:

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class CryptoUtils {
    private static final String AES = "AES";
//  private static byte[] keyValue = new byte[]     // OK 
//          { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
    private static byte[] keyValue = new byte[]     // FAILS !!! WTF!
            { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'z' };

    public static String encrypt(String Data) throws Exception {
        Key key = new SecretKeySpec(keyValue, AES);
        Cipher c = Cipher.getInstance(AES);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        return new BASE64Encoder().encode(encVal);
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = new SecretKeySpec(keyValue, AES);
        Cipher c = Cipher.getInstance(AES);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        return new String(decValue);
    }

    public static void main(String[] args) throws Exception {
        System.out.println(CryptoUtils.encrypt("<PASSWORD>"));
        System.out.println(CryptoUtils.decrypt("Z4i3ywGXil2QCfM6R8S5qw=="));
    }
}

I run this file with the key 'TheBestSecretKey' and everthing's fine.

I run this file with the key 'TheBestSecretKez' and it breaks!

In the latter case it gives me an

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded

inside the decrypt method.

I don't get it. Why does it work in one case and not in the other?

Thanks, Bernhard

3
  • 1
    Not sure what the problem is, it's behaving as expected. The first one is a correct key and second one isn't. The second key will work if you pass the encrypt result directly to the decrypt function without hardcoding the ciphertext which was presumably created with the first key. Also, how did this get so many upvotes? Commented Aug 20, 2015 at 15:02
  • Artjom B. is correct. Your decrypt hard codes the cipher text in the main method, which will be a different value with a different key. Commented Aug 20, 2015 at 16:02
  • I guess, you're right. Still it's counter-intuitive or even misleading, when you want to decrypt sth and it says 'BadPaddingException' instead of 'Cannot decrypt value x with key y'. Commented Aug 21, 2015 at 6:55

1 Answer 1

2

It won't fix your problem, but you should never specify a cipher algorithm without a mode and padding included. The reason being is that it is less secure by default, and there is no guarantee within the specification that indicates the transformation (algorithm/mode/padding) used to encrypt will by default be the same as what is used to decrypt. With security it is always better to be explicit. So this:

Cipher c = Cipher.getInstance(AES);

Should become this:

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

Anywhere you see it.

The problem as Artjom B. pointed out is that your decrypt hard codes the cipher text in the main method, which will be a different value with a different key.

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

1 Comment

Thanks, the last sentence points out the issue here. If a value can't be decrypted, this misleading exception is thrown.

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.