返回

揭秘某东签名算法的奥秘:深入浅出的解析(上)

Android

我们心爱的 Frida 一上场,某东 app 瞬间罢工,白屏加重启,看来是被监测到不对劲了。

在参考文章中,作者提到了一种检测 Frida 的方法(文章链接见文末),为了反检测,我们采取了以下两步:

  • 修改 Frida 签名: 将 Frida 的签名修改为某东 app 的签名,让它看起来像一个正常的组件。
  • 隐藏 Frida 代理: Frida 使用代理的方式与目标 app 进行通信,我们将代理隐藏起来,让它不易被发现。

至此,反检测基本完成。

接下来,我们开始分析某东 app 的签名算法。

1. 逆向分析

使用 jadx 反编译某东 app,定位到签名算法的方法:

public static String a(Context context, String str) {
    try {
        byte[] bytes = str.getBytes("UTF-8");
        byte[] a = a(context, bytes);
        return new String(a, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

从代码中可以看出,签名算法首先将字符串转换为字节数组,然后调用 a 方法进行签名,最后将签名结果转换为字符串返回。

2. a 方法分析

private static byte[] a(Context context, byte[] bArr) {
    int length = bArr.length;
    byte[] bArr2 = new byte[(length + 32)];
    for (int i = 0; i < length; i++) {
        bArr2[i] = bArr[i];
    }
    try {
        byte[] digest = MessageDigest.getInstance("SHA-256").digest(bArr2);
        int length2 = digest.length;
        byte[] bArr3 = new byte[(length2 + 8)];
        for (int i2 = 0; i2 < length2; i2++) {
            bArr3[i2] = digest[i2];
        }
        System.arraycopy(bArr2, length, bArr3, length2, 8);
        byte[] bArr4 = new byte[(length + 32)];
        for (int i3 = 0; i3 < length + 32; i3++) {
            bArr4[i3] = bArr3[i3 % (length + 32)];
        }
        return bArr4;
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

这个方法比较复杂,但本质上就是一个 SHA-256 签名,然后将签名结果和原始数据拼接在一起,再进行一次 SHA-256 签名。

3. 签名结果分析

通过分析代码,我们发现签名结果是一个 64 字节的字符串。前 32 字节是 SHA-256 签名的结果,后 32 字节是原始数据的 SHA-256 签名。

也就是说,签名算法实际上是一个双重 SHA-256 签名。

4. 总结

某东 app 的签名算法是一个双重 SHA-256 签名,先对原始数据进行 SHA-256 签名,然后将签名结果和原始数据拼接在一起,再进行一次 SHA-256 签名。

破解这种签名算法的关键是找到拼接点,然后再分两次进行 SHA-256 签名。