Android AES-расшифровка CBC

#java #android #encryption

#java #Android #шифрование

Вопрос:

Я пытаюсь расшифровать некоторые файлы, зашифрованные в Android AES для целей изучения.

Вот с чего мне начать: (Я изменил имена некоторых методов из запутанной версии, чтобы сделать ее немного более читаемой)

 public class a {
  public static String encode(String paramString) {
    String str = null;
    try {
      byte[] arrayOfByte = encode(getRaw(), paramString.getBytes());
    } catch (Exception exception) {
      exception = null;
    } 
    if (exception != null)
      str = func1((byte[])exception); 
    return str;
  }
  
// func1 and func2 are only used for changing the Exception object. I don't think these are very important.
  private static String func1(byte[] paramArrayOfbyte) {
    if (paramArrayOfbyte == null)
      return ""; 
    StringBuffer stringBuffer = new StringBuffer(paramArrayOfbyte.length * 2);
    for (int i = 0; i < paramArrayOfbyte.length; i  )
      func2(stringBuffer, paramArrayOfbyte[i]); 
    return stringBuffer.toString();
  }
  
  private static void func2(StringBuffer paramStringBuffer, byte paramByte) {
    paramStringBuffer.append("0123456789ABCDEF".charAt(paramByte >> 4 amp; 0xF)).append("0123456789ABCDEF".charAt(paramByte amp; 0xF));
  }
  
  private static byte[] getRaw() throws Exception {
    return KeyGen.generateKey(new byte[] { 
          33, 83, -50, -89, -84, -114, 80, 99, 10, 63, 
          22, -65, -11, 30, 101, -118 }); // this has 16 length. I guess that this is IV.
  }
  
  private static native byte[] getEncrypted(String paramString);
  
  private static byte[] encode(byte[] raw, byte[] clear) throws Exception {
    SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(getKey()));
    return cipher.doFinal(clear);
  }
  
  public static String decode(String paramString) {
    try {
      return new String(decode(getRaw(), getEncrypted(paramString)));
    } catch (Exception exception) {
      return null;
    } 
  }
  
  private static byte[] getKey() {
    try {
      byte[] arrayOfByte = b.decode("IUQSvE6r1TfFPdPEjfklLw==".getBytes("UTF-8"), 2);
      // b.decode is a method as public static native byte[]. 
      if (arrayOfByte != null)
        return KeyGen.generateKey(arrayOfByte); 
    } catch (Exception exception) {}
    return new byte[16];
  }
  
  private static byte[] decode(byte[] raw, byte[] encrypted) throws Exception {
    SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(getKey()));
    return cipher.doFinal(encrypted);
  }
}

 
 public class KeyGen {
  private static native KeyInstance constructKey(String paramString);
  
  public static byte[] generateKey(byte[] maybeIV) {
    if (paramArrayOfbyte != null) {
      KeyInstance keyinstance = constructKey("QrMgt8GGYI6T52ZY5AnhtxkLzb8egpFn3j5JELI8H6wtACbUnZ5cc3aYTsTRbmkAkRJeYbtx92LPBWm7nBO9UIl7y5i5MQNmUZNf5QENurR5tGyo7yJ2G0MBjWvy6iAtlAbacKP0SwOUeUWx5dsBdyhxa7Id1APtybSdDgicBDuNjI0mlZFUzZSS9dmN8lBD0WTVOMz0pRZbR3cysomRXOO1ghqjJdTcyDIxzpNAEszN8RMGjrzyU7Hjbmwi6YNK"); // this has 256 length.
      if (keyinstance != null)
        return extractKey(maybeIV, keyinstance); 
    } 
    return null;
  }
  
  private static native byte[] extractKey(byte[] maybeIV, KeyInstance keyinstance);
  
  private static class KeyInstance {
    public int[] hash = new int[256];
    
    public int x;
    
    public int y;
    
    private a() {}
  }
}
 

Я думаю, что следующее вызывает подозрение, и я могу использовать их как подсказки для получения ключа:

   private static byte[] getRaw() throws Exception {
    return KeyGen.generateKey(new byte[] { 
          33, 83, -50, -89, -84, -114, 80, 99, 10, 63, 
          22, -65, -11, 30, 101, -118 }); // this has 16 length. I guess that this is IV.
  }

// ...
      byte[] arrayOfByte = b.decode("IUQSvE6r1TfFPdPEjfklLw==".getBytes("UTF-8"), 2);
// ...

KeyInstance keyinstance = constructKey("QrMgt8GGYI6T52ZY5AnhtxkLzb8egpFn3j5JELI8H6wtACbUnZ5cc3aYTsTRbmkAkRJeYbtx92LPBWm7nBO9UIl7y5i5MQNmUZNf5QENurR5tGyo7yJ2G0MBjWvy6iAtlAbacKP0SwOUeUWx5dsBdyhxa7Id1APtybSdDgicBDuNjI0mlZFUzZSS9dmN8lBD0WTVOMz0pRZbR3cysomRXOO1ghqjJdTcyDIxzpNAEszN8RMGjrzyU7Hjbmwi6YNK"); // this has 256 length.
 

Кроме того, я заметил, что каждый зашифрованный файл начинается с общей последовательности байтов «42 47 54 31 01 00 00 00».

  1. Куда мне идти дальше, учитывая эти подсказки?
  2. Как я могу прочитать исходный код, объявленный как собственный в файлах .jar?

Комментарии:

1. Каков источник этого кода? Здесь и там есть множество хороших кодов, и вы найдете тот, который использует keygen как IV поколение, которые, черт возьми, называют шифрование encode

2. @kelalaka: Я думаю, что этот код был перепроектирован. Имена методов и переменных были выбраны человеком, использующим инструменты обратного проектирования, а не программистом. Комментарии, вероятно, также были добавлены реверс-инженером. И шифрование здесь, вероятно, предназначено для обфускации, просто чтобы помешать усилиям по обратному проектированию.

3. Машинный код также должен быть в файле APK. Это не будет java.

4. Там есть несколько встроенных методов, и не очевидно, как генерируется ключ. Вы можете попробовать статический анализ файла so, в котором определены эти методы, или динамический анализ APK, поскольку данные, создающие ключ, кажутся статическими. Библиотеки so должны быть в /lib, и вы можете проанализировать их с помощью дизассемблеров / отладчиков, но обычно это не так просто.

5. Часть «для целей изучения» можно игнорировать. Если вы хотите узнать, как работает AES, вы не берете случайный файл и не пытаетесь расшифровать; вы можете пытаться вечно, не получая никакого конкретного представления о том, как работает шифрование / дешифрование. Заголовок гласит «BGT1» в ASCII и, вероятно, сопровождается указанием длины в конце строки или, возможно, дополнительным управлением версиями.