Esqarrouth
Esqarrouth

Reputation: 39181

Android encryption "pad block corrupted" exception

In this code, this line is causing an exception:

clearText = c.doFinal(Base64.decode(encryptedText, Base64.DEFAULT));

javax.crypto.BadPaddingException: pad block corrupted

I got the code from: http://www.techrepublic.com/blog/software-engineer/attention-android-developers-keep-user-data-safe/

Any ideas?

    private String decrypt (String encryptedText) {
        byte[] clearText = null;
        try {
            SecretKeySpec ks = new SecretKeySpec(getKey(), "AES");
            Cipher c = Cipher.getInstance("AES");
            c.init(Cipher.DECRYPT_MODE, ks);
            clearText = c.doFinal(Base64.decode(encryptedText, Base64.DEFAULT));
            return new String(clearText, "UTF-8");
        } catch (Exception e) {
            return null;
        }
    }

Details: I am encrypting it on the android as well

Upvotes: 5

Views: 21051

Answers (4)

BaiJiFeiLong
BaiJiFeiLong

Reputation: 4615

For me, the problem is in getKey()

Make sure that two invocation of getKey() return the same value.

I used new SecureRandom(password.getBytes()) to generate key. It worked on Windows, but on Android, it returned different value for different call.

Upvotes: 1

Siddharth Makadiya
Siddharth Makadiya

Reputation: 733

I Reffred From this : https://androidfreetutorial.wordpress.com/2017/03/14/android-encryptiondecryption-with-aes-algorithm/

Change to "AES" From "AES/ECB/PKCS7Padding";

Upvotes: -1

Maarten Bodewes
Maarten Bodewes

Reputation: 93968

Java + Android + Encryption + Exception means just one thing normally, somebody is using the SecureRandom class again as a key derivation function. This fails when the SecureRandom implementation of "SHA1PRNG" does not behave as the one in Sun's implementation in Java SE. Especially if the seed is added to the state of the random number generator instead of the seed being used as a starting point of the PRNG.

Basically, simply use SecretKey aesKey = new SecretKeySpec(byte[] keyData, "AES") instead, or - if you start off with a password - try and generate the key using PBKDF2.

Upvotes: 6

Esqarrouth
Esqarrouth

Reputation: 39181

owlstead's advice was helpful, but for this case when using the code in

Attention Android developers: Keep user data safe http://www.techrepublic.com/blog/software-engineer/attention-android-developers-keep-user-data-safe/

I made some changes to the code that might be helpful for other people in the future. I completely deleted the getkey method.

private static String seed;

/**
 * Encrypts the text. 
 * @param clearText The text you want to encrypt
 * @return Encrypted data if successful, or null if unsucessful
 */
protected String encrypt(String clearText) {
    byte[] encryptedText = null;
    try {
        byte[] keyData = seed.getBytes();
        SecretKey ks = new SecretKeySpec(keyData, "AES");
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, ks);
        encryptedText = c.doFinal(clearText.getBytes("UTF-8"));
        return Base64.encodeToString(encryptedText, Base64.DEFAULT);
    } catch (Exception e) {
        return null;
    }
}

/**
 * Decrypts the text
 * @param encryptedText The text you want to encrypt
 * @return Decrypted data if successful, or null if unsucessful
 */
protected String decrypt (String encryptedText) {
    byte[] clearText = null;
    try {
        byte[] keyData = seed.getBytes();
        SecretKey ks = new SecretKeySpec(keyData, "AES");
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, ks);
        clearText = c.doFinal(Base64.decode(encryptedText, Base64.DEFAULT));
        return new String(clearText, "UTF-8");
    } catch (Exception e) {
        return null;
    }
}   

Upvotes: 11

Related Questions