#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».
- Куда мне идти дальше, учитывая эти подсказки?
- Как я могу прочитать исходный код, объявленный как собственный в файлах .jar?
Комментарии:
1. Каков источник этого кода? Здесь и там есть множество хороших кодов, и вы найдете тот, который использует keygen как IV поколение, которые, черт возьми, называют шифрование encode
2. @kelalaka: Я думаю, что этот код был перепроектирован. Имена методов и переменных были выбраны человеком, использующим инструменты обратного проектирования, а не программистом. Комментарии, вероятно, также были добавлены реверс-инженером. И шифрование здесь, вероятно, предназначено для обфускации, просто чтобы помешать усилиям по обратному проектированию.
3. Машинный код также должен быть в файле APK. Это не будет java.
4. Там есть несколько встроенных методов, и не очевидно, как генерируется ключ. Вы можете попробовать статический анализ файла so, в котором определены эти методы, или динамический анализ APK, поскольку данные, создающие ключ, кажутся статическими. Библиотеки so должны быть в /lib, и вы можете проанализировать их с помощью дизассемблеров / отладчиков, но обычно это не так просто.
5. Часть «для целей изучения» можно игнорировать. Если вы хотите узнать, как работает AES, вы не берете случайный файл и не пытаетесь расшифровать; вы можете пытаться вечно, не получая никакого конкретного представления о том, как работает шифрование / дешифрование. Заголовок гласит «BGT1» в ASCII и, вероятно, сопровождается указанием длины в конце строки или, возможно, дополнительным управлением версиями.