I'm trying to reverse engineering an android app API so this is what I tried:

First the app was using Okhttp certificate pinning and I couldn't track the URLs with Charles then I tried this method and now the tracking part is working but the request body is encrypted and I really can't understand the method of encryption because all of the requests have different length and its not like Base64 here like this example :


now I'm trying to decompile the APK and try to understand the encryption method. so I decompile the APK then start to find endpoints (this app using okhttp and retrofit), I found the endpoint I wanted

Call<Object> m3550a(@Header("Content-Type") String str, @Body String str2);

then I tried to rebuild the process of sending this endpoint to simulate the request and encryption but not only its so hard (Java decompiler and Jadx cant decompile all the methods and some of them have exception) but some the methods have bad parameters like this method :

public static String j(Context context) {
    try {
        return aa.a(context);
    } catch (Exception e2) {
        return a;

and the aa.a() method :

public static String a(byte[] bArr) {
    char[] cArr = new char[(bArr.length * 2)];
    for (int i = 0; i < bArr.length; i++) {
        int i2 = bArr[i] & 255;
        int i3 = i * 2;
        cArr[i3] = c[i2 >>> 4];
        cArr[i3 + 1] = c[i2 & 15];
    return new String(cArr);

is there any way to do this easier i searched the decompiled folder for encrption methods and i find this codes :

Cipher :

public class C1355f {
/* renamed from: a */
public static String f3576a = "MIGfMA0GCSqGSIb3DQEBAQUAA4GSADCBiQKBgQCVSNDQlVBMy2Wh4J3usfQydpwIzY6FwqDwV0Dd+Bk6PA5sc3usQ8mmjLiI2YD1RDv4jjvmAdkXK+HXuxm2fI6XeIQvgnPRaaj9yNcJnFNViogidcFO7Kg2YYj8yj6DgnCkAtgJeUx2DVvyPnv+Vk1q37Tg4qW0dEFNkWL9hKXGSwIDAQAB";

/* renamed from: a */
public static byte[] m3787a(String str, String str2) throws Exception {
    try {
        str = C1355f.m3786a(str);
        str2 = str2.getBytes("UTF8");
        byte[] bArr = new byte[16];
        Arrays.fill(bArr, (byte) 0);
        AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(bArr);
        Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
        instance.init(1, str, ivParameterSpec);
        return instance.doFinal(str2);
    } catch (String str3) {
        throw new Exception(str3);

/* renamed from: a */
public static SecretKeySpec m3786a(String str) throws UnsupportedEncodingException {
    Object obj = new byte[16];
    Arrays.fill(obj, (byte) 0);
    str = str.getBytes("UTF-8");
    System.arraycopy(str, 0, obj, 0, str.length < obj.length ? str.length : obj.length);
    return new SecretKeySpec(obj, "AES");

/* renamed from: a */
public static byte[] m3788a(byte[] bArr, String str) throws Exception {
    bArr = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(bArr));
    Cipher instance = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    instance.init(1, bArr);
    return instance.doFinal(str.getBytes());

Base64 :

private byte[] f8405h = new byte[0];
Base64.encodeToString(this.f8405h, 2)

sorry if this question is a mess but i need help anything can be helpfull

1 Answer 1


JADX often provides inaccurate de-compilation output. You'll have to look at the smali in methods that you find inconsistent.
About the wrong parameter in the aa.a method, you'll have to check the smali to make sure you've got the right class and the right method because I never saw JADX get the types wrong.

Now, about the request body, it seems like it's the base64 of some encrypted bytes. If I were you I'd look for xrefs for the endpoint retro fit method, and see how the arguments are generated.
You could also try to hook the methods from the cipher class you found and compare that to what you see in the requests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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