0

I believe this is a snippet from androidsnippets.org - why this isn't funcioning on Android 2.3? How to fix it?

Error

03-05 23:19:17.479: WARN/System.err(3598): javax.crypto.BadPaddingException: pad block corrupted
03-05 23:19:17.518: WARN/System.err(3598):     at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:715)
03-05 23:19:17.518: WARN/System.err(3598):     at javax.crypto.Cipher.doFinal(Cipher.java:1090)

I found several answers on this topic but I couldn't find a decent way how to fix this, add NoPadding parameter or different algorithm or..?

public static String code(String stringToCode) {
    try {
        stringToCode = encrypt("somekey",stringToCode);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    return stringToCode;
}

public static String decode(String stringToDecode) {
    try {
        stringToDecode = decrypt("somekey",stringToDecode);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    return stringToDecode;
}

public static String encrypt(String seed, String cleartext) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext.getBytes());
    return toHex(result);
}

public static String decrypt(String seed, String encrypted) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] enc = toByte(encrypted);
    byte[] result = decrypt(rawKey, enc);
    return new String(result);
}

private static byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(seed);
    kgen.init(128, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    return raw;
}


private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] decrypted = cipher.doFinal(encrypted);
    return decrypted;
}

public static String toHex(String txt) {
    return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
    return new String(toByte(hex));
}

public static byte[] toByte(String hexString) {
    int len = hexString.length()/2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++)
        result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
    return result;
}

public static String toHex(byte[] buf) {
    if (buf == null)
        return "";
    StringBuffer result = new StringBuffer(2*buf.length);
    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
    return result.toString();
}

private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
svenkapudija
  • 5,128
  • 14
  • 68
  • 96

3 Answers3

1

Two points:

1) The toByte() method isn't clear what it's trying to do, but I'll bet it's wrong, as the line

int len = hexString.length()/2;

is going to give the same result of 3 for strings of length 6 and 7 (say)

2) You can't rely on converting stings to byte arrays without specifying the Charset to use. Different locales and different run machines may have different default Charsets. You should probably use str.getBytes("UTF8") in the algorithm.

NickT
  • 23,844
  • 11
  • 78
  • 121
  • I'll do some more testing, but Charset seemed to be a problem... :) – svenkapudija Mar 05 '11 at 23:34
  • Right...it works then on Gingerbread (2.3) but not on Froyo (2.2) and vice-versa. If I remove charset parameter, it works on 2.2 but not on 2.3. – svenkapudija Mar 06 '11 at 20:46
  • Here is the same problem - what's the solution then? Use some other algorithms? http://stackoverflow.com/questions/4536241/aes-gingerbread – svenkapudija Mar 07 '11 at 13:32
1

NickT says: "is going to give the same result of 3 for strings of length 6 and 7 (say)" I suppose that length of HEX string in that case is always EVEN number (see function appendHex)

a4vi2r
  • 101
  • 1
  • 5
0

It's problem with BouncyCastle (BouncyCastle AES error when upgrading to 1.45).

What I have found is that this results in two different values for BC 1.34 vs 1.45.

I couldn't find the solution, yet...

Community
  • 1
  • 1
svenkapudija
  • 5,128
  • 14
  • 68
  • 96