首页 > 解决方案 > 我如何解密多次加密的字符串到Android中的以下代码?

问题描述

static MediaType f865a = MediaType.parse("application/json");

    private static String f866b = "IV_VALUE_16_BYTE";
    private static String c = "Egov";
    private static String d = "SALT_VALUE";
    private static String e = "PBKDF2WithHmacSHA1";
    private static String f = "eMethod219";
    private static String g = "AES";
private static String m = "AES/CBC/PKCS5Padding";

    private static String h = "eMethod486";
    private static String i = "eMethod269";
    private static String j = "eMethod580";

private String a(byte[] bArr) {
        return new String(bArr, "UTF-8");
    }

    private Key a() {
        return new SecretKeySpec(SecretKeyFactory.getInstance(e).generateSecret(new PBEKeySpec(c.toCharArray(), c(d), 65536, 128)).getEncoded(), g);
    }

    private Cipher a(int i2) {
        Cipher instance = Cipher.getInstance(m);
        instance.init(i2, a(), new IvParameterSpec(c(f866b)));
        return instance;
    }

    private byte[] c(String str) {
        return str.getBytes("UTF-8");
    }

    public String a(String str) {
        Log.d("decode", str);
        return new String(a(2).doFinal(a.b(c(str))));
    }

    public String a(String str, String str2, String str3) {
        String str4;
        IOException e2;
        OkHttpClient build = new OkHttpClient.Builder().connectTimeout(120, TimeUnit.SECONDS).writeTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS).build();
        String str5 = k + "/" + h;
        String str6 = "{\"EPara1\":\"" + b(str) + "\", \"EPara2\" :\"" + b(str2) + "\",\"EPara3\" :\"" + b(str3) + "\"}";
        String str7 = "test";
        try {
            str4 = build.newCall(new Request.Builder().url(str5).post(RequestBody.create(f865a, "\"" + b(str6) + "\"")).build()).execute().body().string();
            try {
                Log.d("Encrypt", str4);
            } catch (IOException e3) {
                str7 = str4;
                e2 = e3;
            }
        } catch (IOException e4) {
            e2 = e4;
            e2.printStackTrace();
            str4 = str7;
            str4 = a(str4);
            Log.d("Decrypt", str4);
            return str4;
        }
        try {
            str4 = a(str4);
        } catch (Exception e5) {
            e5.printStackTrace();
        }
        Log.d("Decrypt", str4);
        return str4;
    }

所以我通过反编译 apk 得到了这个有趣的代码片段。现在我用frida来监控和追踪密码。我多次尝试解密应用程序用来向API发出请求的字符串。我使用Burp 套件拦截了请求,但请求正文已加密。关于如何解密加密的任何想法以及我从请求中获得的响应都使用相同的算法进行加密和解密

同样在对apk进行去混淆之后,我发现了类似的代码:

private byte[] decode(String str) {
        return str.getBytes("UTF-8");
    }

    private String get(byte[] bArr) {
        return new String(bArr, "UTF-8");
    }

    private Key get() {
        return new SecretKeySpec(SecretKeyFactory.getInstance(value).generateSecret(new PBEKeySpec(key.toCharArray(), decode(t), 65536, 128)).getEncoded(), k);
    }

    private Cipher init(int i2) {
        Cipher $r3 = Cipher.getInstance(H);
        $r3.init(i2, get(), new IvParameterSpec(decode(n)));
        return $r3;
    }

    /* access modifiers changed from: package-private */
 public String getString(String str, String str2, String str3) {
        IOException $r17;
        OkHttpClient $r6 = new OkHttpClient.Builder().connectTimeout(120, TimeUnit.SECONDS).writeTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS).build();
        String $r1 = get(str);
        String $r2 = get(str2);
        String $r7 = get(str3);
        String $r3 = this$0 + "/" + e;
        String $r12 = "{\"EPara1\":\"" + $r1 + "\", \"EPara2\" :\"" + $r2 + "\",\"EPara3\":\"" + $r7 + "\"}";
        String $r13 = "\"" + get($r12) + "\"";
        Log.d("teeeee", $r13);
        String $r22 = "test";
        try {
            String $r14 = $r6.newCall(new Request.Builder().url($r3).post(RequestBody.create(c, $r13)).build()).execute().body().string();
            $r22 = $r14;
            try {
                Log.d("Encrypt", $r14);
            } catch (IOException $r16) {
                $r22 = $r14;
                $r17 = $r16;
            }
        } catch (IOException e2) {
            $r17 = e2;
            $r17.printStackTrace();
            $r22 = read($r22);
            Log.d("Decrypt", $r22);
            return $r22;
        }
        try {
            $r22 = read($r22);
        } catch (Exception $r18) {
            $r18.printStackTrace();
        }
        Log.d("Decrypt", $r22);
        return $r22;
    }


  public String get(String str) {
        try {
            return get(Base64.encodeBase64URLSafe(init(1).doFinal(decode(str))));
        } catch (Throwable $r4) {
            throw new RuntimeException($r4);
        }
    }

标签: androidencryptionfrida

解决方案


在某些时候,您会看到数据进入加密函数,那么为什么不直接将其捕获呢?

无论如何,这是我脚本中的一个片段。我使用 frida.send() 而不是 console.log,可能需要在需要的地方修改和添加。

 var secretKeySpecDef = Java.use('javax.crypto.spec.SecretKeySpec');

 var ivParameterSpecDef = Java.use('javax.crypto.spec.IvParameterSpec');

 var ivParameterSpecDef_init_1 = ivParameterSpecDef.$init.overload('[B');

 var cipherDoFinal_1 = cipherDef.doFinal.overload();
var cipherUpdate_1 = cipherDef.update.overload('[B');

    
var secretKeySpecDef_init_1 = secretKeySpecDef.$init.overload('[B', 'java.lang.String');

    secretKeySpecDef_init_1.implementation = function (arr, alg) {
        send("Creating " + alg + " key plaintext: " + toHexString(arr));
        return secretKeySpecDef_init_1.call(this, arr, alg);
    }

 cipherDoFinal_1.implementation = function () {
        var ret = cipherDoFinal_1.call(this);
        send(this.getIV(), this.getAlgorithm(), complete_bytes, ret);
        // complete_bytes = array used for ciperUpdate. Add your own message
        return ret;
    }

cipherUpdate_1.implementation = function (arr) {
        addtoarray(arr); 
   // Adds to an array object to be used in cipherDoFinal
// Add your own code here
        return cipherUpdate_1.call(this, arr);
    }


推荐阅读