JAVA 解密 - 对 Android 应用程序进行逆向工程

逆向工程 安卓 爪哇
2021-07-09 03:03:56

我正在尝试解密一个加密的字符串,但我被困在Ciper.doFinal()解密抛出一个BadPaddingException. 有问题的字符串是3qBogw/PIqpErH/DyEHLTQ==我知道的一件事是解密时的字符串包含一个数字(它用于Integer.valueOf()

首先,调用以下方法;

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" });
}

这里没什么特别的,只是创建一个 UUID 并用一个常量字符串连接它,还使用 ​​Apache StringUtils 将所有出现的 dCp 替换为 gP -(不知道为什么需要)

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 "";
   }
}

在解密方法中,生成的随机值被传递给一个方法,以便将其转换为字节数组。下面是那个方法,

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;
}

这里也没什么特别的,只是返回一个从String.getBytes()方法中获得的字节数组但有趣的是只使用了前 16 个字节。这就是让我担心的地方,如果您仔细查看,在getRandom()它们连接一个UUID字符串和另一个常量字符串的方法中。但是一旦将相同的字符串传递给此方法,字符串的其余部分将被忽略。

然后最后 ciperDecrypt 方法使用 aCiper来解密字符串。

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;
}

这个过程看起来不错,但是当我尝试执行它时,我BadPaddingExceptiondoFinal()执行行时得到一个我怀疑是在创建byte[]有一些数据丢失的地方。

如果有人能确定我哪里出错了,那将非常有帮助。我真的很感激,谢谢!

1个回答

认为您的解密是错误的,可能是因为您使用了错误的密钥。

如果我没有记错,PKCS5让你有种检测故障解密。原因是 PKCS5 期望解密的数据采用特殊的填充格式。如果您的解密失败,则不遵守填充格式,因此它会抱怨填充错误。

没有查过,举个例子:

假设我将 PKCS5 填充用于我的输入(长度为 10 字节),块大小为 16 字节。正确填充它看起来像这样:

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

最后的06字节是填充字节,它们的值必须是有多少个填充字节。

因此,如果您解密某些内容并且最后一个n字节(n=最后一个字节的字节值)不是n,PKCS5 会抱怨填充错误。

根据我的经验,由于错误的密钥而导致解密错误。