Search code examples
javaandroidcryptographyaesbouncycastle

AES cipher text is different


I am using AES encrypting with bouncy castle implementation in both Android and in a Java servlet environment. The encryption part is ok in both scenario. However I get different result for those 2 platforms once I encrypt the same text with same key.

My intention is to do an encryption in Android and do the decryption in web environment.

This is the only change I have done for Android AES implementation.

    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = null;
    if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {
        sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    } else {
        sr = SecureRandom.getInstance("SHA1PRNG");
    }
    sr.setSeed(key);
    kgen.init(128, sr);
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();

Above I just add the Crypto into get instance.

I used the spongy castle implementation as well to see whether I can accomplish this. Still it gave me the same result as Android gives. Not sure whether I have loaded it properly. I tested this on API level 14 and 17.

This leads to javax.crypto.BadPaddingException: pad block corrupted.


Solution

  • For anyone who is referencing this thread this is the change I did to my code. Now it works well in Android and server environment.

    Answer is taken from,

    Android 4.2 broke my encrypt/decrypt code and the provided solutions don't work

    Thanks @kroot

        /* Store these things on disk used to derive key later: */
        int iterationCount = 1000;
        int saltLength = 32; // bytes; should be the same size as the output
                                // (256 / 8 = 32)
        int keyLength = 256; // 256-bits for AES-256, 128-bits for AES-128, etc
        byte[] salt = new byte[saltLength]; // Should be of saltLength
    
        /* When first creating the key, obtain a salt with this: */
        SecureRandom random = new SecureRandom();
        random.nextBytes(salt);
    
        /* Use this to derive the key from the password: */
        KeySpec keySpec = new PBEKeySpec(new String(key,
                Constants.CHAR_ENCODING).toCharArray(), key, iterationCount,
                keyLength);
        SecretKeyFactory keyFactory = SecretKeyFactory
                .getInstance("PBEWithSHA256And256BitAES-CBC-BC");
        byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
        SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
    
        return secretKey.getEncoded();