此apk各种脱壳混淆导致很难反编译,记录核心内容方便解密
解密内容 = (com.dep.xxx.utils.p.b(加密串, 解密KEY));
p.b的class还原
package com.dep.xxx.utils; import android.util.Base64; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.net.SocketException; import java.net.URL; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Random; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /* loaded from: classes12.dex */ public class p { private static final String a = "AES"; /* renamed from: b reason: collision with root package name */ public static final int f20374b = 16; /* renamed from: c reason: collision with root package name */ private static final Charset f20375c = StandardCharsets.UTF_8; /* renamed from: d reason: collision with root package name */ private static final String f20376d = "0"; /* renamed from: e reason: collision with root package name */ private static final String f20377e = "AES/ECB/PKCS7Padding"; /* renamed from: f reason: collision with root package name */ private static final String f20378f = "AES/CBC/PKCS7Padding"; private static void a(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception e2) { e2.printStackTrace(); com.biguo.utils.b.e.c("dddd", Arrays.toString(e2.getStackTrace()), e2); } } } public static String b(String str, String str2) { try { byte[] decode = Base64.decode(str, 2); Cipher cipher = Cipher.getInstance(f20377e); cipher.init(2, f(str2)); return new String(cipher.doFinal(decode), f20375c); } catch (Exception e2) { e2.printStackTrace(); return null; } } public static File c(String str, String str2, String str3, String str4) throws Exception { try { CipherInputStream cipherInputStream = new CipherInputStream(new URL(str).openStream(), g(str4, 2)); File file = new File(str2, str3); FileOutputStream fileOutputStream = new FileOutputStream(file); byte[] bArr = new byte[8192]; while (true) { int read = cipherInputStream.read(bArr); if (read != -1) { fileOutputStream.write(bArr, 0, read); fileOutputStream.flush(); } else { fileOutputStream.close(); cipherInputStream.close(); return file; } } } catch (Exception e2) { e2.printStackTrace(); com.biguo.utils.b.e.c("dddd", Arrays.toString(e2.getStackTrace()), e2); throw new SocketException(); } } public static String d(String str, String str2) { try { Cipher cipher = Cipher.getInstance(f20377e); cipher.init(1, f(str2)); return Base64.encodeToString(cipher.doFinal(str.getBytes(f20375c)), 0); } catch (Exception e2) { e2.printStackTrace(); com.biguo.utils.b.e.c("dddd", Arrays.toString(e2.getStackTrace()), e2); return null; } } public static File e(String str, String str2, String str3, String str4) { try { CipherInputStream cipherInputStream = new CipherInputStream(new FileInputStream(str), g(str4, 1)); File file = new File(str2, str3); FileOutputStream fileOutputStream = new FileOutputStream(file); byte[] bArr = new byte[8192]; while (true) { int read = cipherInputStream.read(bArr); if (read != -1) { fileOutputStream.write(bArr, 0, read); fileOutputStream.flush(); } else { cipherInputStream.close(); a(fileOutputStream); return file; } } } catch (Exception e2) { e2.printStackTrace(); com.biguo.utils.b.e.c("dddd", Arrays.toString(e2.getStackTrace()), e2); return null; } } public static SecretKeySpec f(String str) { return new SecretKeySpec(i(str).getBytes(f20375c), a); } private static Cipher g(String str, int i2) { try { SecretKeySpec f2 = f(str); Cipher cipher = Cipher.getInstance(f20378f); cipher.init(i2, f2, new IvParameterSpec(new byte[cipher.getBlockSize()])); return cipher; } catch (Exception e2) { e2.printStackTrace(); com.biguo.utils.b.e.c("dddd", Arrays.toString(e2.getStackTrace()), e2); return null; } } public static String h() { StringBuilder sb = new StringBuilder(); Random random = new Random(System.currentTimeMillis()); while (sb.length() < 16) { int nextInt = random.nextInt(26); if (random.nextInt(2) % 2 == 0) { sb.append((char) (nextInt + 65)); } else { sb.append((char) (nextInt + 97)); } } return sb.toString(); } private static String i(String str) { int length = str.length(); if (length < 16) { StringBuilder sb = new StringBuilder(); sb.append(str); for (int i2 = 0; i2 < 16 - length; i2++) { sb.append("0"); } return sb.toString(); } return str; } }
再看看解密Key来源
String b2 = com.dep.xxx.utils.n0.b(baseResponse.getData().getKey(), PracticeV3Presenter.this.f15272q[1]);
可以看到需要找到f15272q,核心代码如下
public String i0() { try { String[] e2 = com.dep.xxx.utils.n0.e(); this.f15272q = e2; com.biguo.utils.b.e.a("dddd", e2); if (this.f15272q[0].startsWith(c.c.f1719m)) { this.f15272q[0] = this.f15272q[0].substring(1); } if (this.f15272q[0].endsWith(c.c.f1719m)) { this.f15272q[0] = this.f15272q[0].substring(0, this.f15272q[0].length() - 1); } return Base64.encodeToString(String.format("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----", this.f15272q[0]).getBytes(), 0); } catch (NoSuchAlgorithmException unused) { ((e4.b) this.f36061d).U3("秘钥生成失败,请联系客服"); return ""; } }
核心还是在utils.n0.e()
public static String[] e() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); KeyPair generateKeyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = generateKeyPair.getPrivate(); return new String[]{Base64.encodeToString(generateKeyPair.getPublic().getEncoded(), 0), Base64.encodeToString(privateKey.getEncoded(), 0)}; }
本地生成了rsa证书,公钥转base64请求通过get发送给服务端,例如
https://www.xxx.com/api/v5/exams/getQuestionBank?code=03708&mainType=4&public_key=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDVFJqRUhDc3pZNFo3VENVdlBueFphNE1yUQp4MzJoQy8zd2MrNW9wNWQyWWo5SitJNTZzT0NkUC9McVB2Yzlna1lPeTUrblg3QXFyVEovOVhOYmZjN3E4WENRCjFxblQ5ZW1TRm9XR3Y1WjUrY29oeHlhV21CVnVkMkZYUlhoUldlL295aDlZUk9EMStnbUxidEU1RVBnTHcwdzQKZFVBOFhreG41VTJHdjF6b0hRSURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==&isAllExam=1&professions_id=4626&cert_type=0&layer_id=1&school_id=92&province_id=21&users_id=1851315&city_id=220
待验证数据
{"result_code":1,"result_info":"请求成功","data":{"source":"file","key":"ghIIs6gpDPsGf4gqZfY2UYLqYe\/7Fr\/b2BYDWtze8U0Bl7R3SAiXhD3CXRHY62V9OKO9lqCNXDQ9vO+ncmhovXq76eEPTs00xuu01+\/rOu6vllUtx\/dBP+oxKKJEmLg5m7Ul\/m6Tk2fVqknJ\/Uzu0xfcwQzOseNhl49VKF7Sag4=","topics":[],"fileUrls":["masterTopicList\/topicList-mainType_4-code_00910-topicType_1-version_1729066317.json","masterTopicList\/topicList-mainType_4-code_00910-topicType_2-version_1729066317.json","masterTopicList\/topicList-mainType_4-code_00910-topicType_4-version_1729066317.json"]}}
c#中string和StringBuilder直接看看执行速度。(2).String类型累计赋值Test  ...
1.全局用户信息设置 git config --global user.name gaojiufeng git config --global user.email 392223903...
1.远程仓库的协作模式开发者把自己最新的版本推到线上仓库,同时把线上仓库的最新代码,拉到自己本地即可2.注册git帐号国外: http://www.github.com国内: http://git.oschina.net2.在码云创建项目,不要初始化readmegit push https://gi...
日志查看:git log版本切换:方式1:git reset --hard HEAD^ 倒退一个版本git reset --hard HEAD^^ 倒退两个版本方式2:(版本号的形式,建议版本号码补充完...
1.关机Process.Start("shutdown", "-s -t 0"); 2. 注销 Proc...
首先网页全部是纯静态的文件,本地测试正常访问,服务器端无法加载CSS,并且无法查看CSS文件的内容。 解决方案:关闭网站的压缩->>静态压缩和动态压缩...