如何解密Android JSON有效负载?

时间:2019-01-12 14:41:32

标签: java android encryption

我通常是Android和Java的新手,我想检查特定应用程序的工作原理,因此我首先使用apktool对应用程序进行反编译,然后使用jadx浏览源代码文件,到目前为止一切都有意义,因此我添加了mitmproxy来检查应用程序的网络流量。

我知道请求回复是JSON负载,但是可能使用mcryptopenssl加密了其中的一些?因此跟踪方法将我引导至该文件。

import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class MC {
    private IvParameterSpec a;
    private SecretKeySpec b;
    private Cipher c;

    private native int getint();

    public native String I6MOYF();

    static {
        System.loadLibrary("native-lib");
    }

    public MC(String str) {
        this.a = new IvParameterSpec(str.getBytes());
        this.b = new SecretKeySpec((I6MOYF() + String.valueOf(getint())).getBytes(), "AES");
        try {
            this.c = Cipher.getInstance("AES/CBC/NoPadding");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e2) {
            e2.printStackTrace();
        }
    }

    public byte[] encrypt(String str) throws Exception {
        if (str == null || str.length() == 0) {
            throw new Exception("Empty string");
        }
        try {
            this.c.init(1, this.b, this.a);
            return this.c.doFinal(a(str).getBytes());
        } catch (Exception e) {
            throw new Exception("[encrypt] " + e.getMessage());
        }
    }

    private static String a(String str) {
        int length = 16 - (str.length() % 16);
        for (int i = 0; i < length; i++) {
            str = str + 0;
        }
        return str;
    }

    public byte[] des(String str) throws Exception {
        if (str == null || str.length() == 0) {
            throw new Exception("Empty string");
        }
        try {
            this.c.init(2, this.b, this.a);
            Object doFinal = this.c.doFinal(hexToBytes(str));
            if (doFinal.length > 0) {
                int i = 0;
                for (int length = doFinal.length - 1; length >= 0; length--) {
                    if (doFinal[length] == (byte) 0) {
                        i++;
                    }
                }
                if (i > 0) {
                    Object obj = new byte[(doFinal.length - i)];
                    System.arraycopy(doFinal, 0, obj, 0, doFinal.length - i);
                    return obj;
                }
            }
            return doFinal;
        } catch (Exception e) {
            throw new Exception("[decrypt] " + e.getMessage());
        }
    }

    public static byte[] hexToBytes(String str) {
        byte[] bArr = null;
        if (str != null && str.length() >= 2) {
            int length = str.length() / 2;
            bArr = new byte[length];
            for (int i = 0; i < length; i++) {
                bArr[i] = (byte) Integer.parseInt(str.substring(i * 2, (i * 2) + 2), 16);
            }
        }
        return bArr;
    }
}

我了解它使用OpenSSL“ AES / CBC / NoPadding”模式解密有效负载,但是我不知如何获取有效负载并手动进行操作。

这是服务器提供的有效负载的示例,应用程序发送密钥头,但是更改和删除它不会更改有效负载,因此我得出结论,它并未使用用于实际加密的密钥

AwFpdchYa7twLSEwN884uGQ/CNoLKrGBxtwIXGcL9OQTPPh96I1uhuh85HXLw3XUikVCmKaKgnssGorqYuvHQELce3nAhnaeHDcEsMFIykeitgDWLXeCed6f9UXHn+XF8nC3arHVbhMgIW8bUlWMq6KygRb4jeUufRHJzJ7LK0q6TvY+rF+utv3i//3NCuKfmbiiMlBvyDdMWPIL83YywkdjLujbBn0RNaeqUDjE0I7xqYypWPjwPXH1DZPbnGFYHemJgNS8QKtFnbtiRwEhpzx2sEoe/NBIgvcXsYkRSgrt+Q==

主要问题是,您将如何使用提供的代码手动解密有效载荷?

编辑:

如@Robert先生所建议,我试图查看如何调用本机函数,因此我在Android模拟器上安装了frida-server,这是一个有趣的调用,不确定该怎么做

/* TID 0x10b1 */
15066 ms  open(pathname="/data/app/com.friga.gameapp-lPtwMqeZ36x47-Yo8YDzOg==/lib/x86/libnative-lib.so", flags=0x0)

我猜这应该是关键吗? -lPtwMqeZ36x47-Yo8YDzOg==

1 个答案:

答案 0 :(得分:0)

我通过遵循11x256博客的“ Frida hooking android part 5: Bypassing AES encryption”帖子,成功地使用frida解决了问题