2

I am trying to decrypt an encrypted string, but I am stuck in Ciper.doFinal() where the decryption throws a BadPaddingException. The string in question is 3qBogw/PIqpErH/DyEHLTQ==. One thing I know is that the string when decrypted contains a number (It is used in Integer.valueOf())

First, the following method is called;

public static String getRandom() {
    String str1 = UUID.randomUUID().toString();
    String str2 = dCpw^jDyaip^Hfy]XgdRbp_imwbheJCFxTF^ligkteDEdrbtsu\yIV[;
    StringBuilder localStringBuilder = new StringBuilder();
    localStringBuilder.append(str1);
    localStringBuilder.append(str2);
    return StringUtils.replaceEachRepeatedly(localStringBuilder.toString(), new String[] { "dCp" }, new String[] { "gPs" });
}

Nothing too fancy here just creates a UUID and concats it with a constant string and also uses Apache StringUtils to replace all occurances of dCp to gPs - (not sure why that is required)

public static String decrypt(String str) {
   try {
      String random = getRandom();
      byte[] decode = Base64.decode(str, 0);
      byte[] array = convertToArray(random);
      return new String(ciperDecrypt(decode, array, array), "UTF-8");
   } catch (Exception e) {
      e.printStackTrace();
      return "";
   }
}

Here in the decrypt method, the generated random value is passed to a method in order to convert it to a byte array. Following is that method,

private static byte[] convertToArray(String str) throws UnsupportedEncodingException {
    byte[] obj = new byte[16];
    byte[] bytes = str.getBytes("UTF-8");
    int length = str.length();
    System.arraycopy(bytes, 0, obj, 0, Math.min(bytes.length, obj.length));
    return obj;
}

There is nothing fancy here too, just returns a byte array obtained from String.getBytes() methods. But what is interesting is that only first 16 bytes are used. This is what worries me, if you look at this carefully, in the getRandom() method they concat a UUID string and another constant string. But once the same string is passed to this method, the rest of the string is ignored.

And then finally ciperDecrypt method uses a Ciper to decrypt the string.

public static byte[] ciperDecrypt(byte[] paramArrayOfByte1, byte[] paramArrayOfByte2, byte[] paramArrayOfByte3) {
    try {
        Cipher localCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec secret = new SecretKeySpec(paramArrayOfByte2, "AES");
        IvParameterSpec param = new IvParameterSpec(paramArrayOfByte3);
        localCipher.init(2, secret, param);
        return localCipher.doFinal(paramArrayOfByte1);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

This procedure looks fine, but when I try to execute it, I get a BadPaddingException when the doFinal() line is executed. What I suspect is in the creation of the byte[] where there is some data loss.

It would be really helpful if anyone can identify where I have gone wrong. I would really appreciate it, Thanks!

  • Adding to my answer - I guess the key really seems to be wrong because it makes no sense. It decrypts a fixed string with a random key (first 16 bytes of the UUID), I don't see how this would ever work without sheer luck. – Johann Aydinbas May 15 '18 at 3:44
  • Instead of trying to reverse engineer the encryption algorithm, you can try hooking the original decryption function using frida (frida.re/docs/android) – Madushan May 16 '18 at 17:23
1

I think your decryption is wrong, possibly because you use a wrong key.

If I remember correctly, PKCS5 allows you to kind of detect faulty decrypts. The reason is that PKCS5 expects decrypted data to be in a special padding format. If your decryption fails, the padding format isn't adhered to and thus it complains about bad padding.

Without having looked it up, an example:

Say I use PKCS5 padding for my input (length 10 bytes) for a block size of 16 bytes. Properly padded it would look like this:

Data      xx xx xx xx xx xx xx xx xx xx 06 06 06 06 06 06

The 06 bytes at the end are padding and their value must be how many padding bytes there are.

So if you decrypt something and the last n bytes (n = byte value of last byte) aren't n, PKCS5 will complain about bad padding.

In my experience that happens with faulty decryptions due to wrong key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.