APK校验和- 二进制代码保护

3

我该如何在安卓中计算APK文件的校验和?我想要计算APK的校验和,并且每次执行我的应用程序时进行比较,以查看是否有人修改了二进制代码。我该如何计算校验和并实现这一点?

1个回答

2
2020年更新 - Google Play现在可以优化、重新打包和重新签名已上传的.apk文件(并向.apk文件添加安全元数据),因此这个篡改检查可能已经无效了。最好使用SafetyNet认证API来验证设备和您的应用程序 - 只需确保您在服务器上离线验证签名即可。
以下是一些代码,用于对您的APK进行校验和。我写了一篇文章,介绍如何向您的应用程序添加篡改检测(具有讽刺意味的是,该文章没有包括apk校验和)。
private static long getApkFileChecksum(Context context) {
        String apkPath = context.getPackageCodePath();
        Long chksum = null;
        try {
            // Open the file and build a CRC32 checksum.
            FileInputStream fis = new FileInputStream(new File(apkPath));
            CRC32 chk = new CRC32();
            CheckedInputStream cis = new CheckedInputStream(fis, chk);
            byte[] buff = new byte[80];
            while (cis.read(buff) >= 0) ;
            chksum = chk.getValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return chksum;
    }

你也可以使用这个来对你的apk进行sha-256哈希。
public static String getApkFileDigest(Context context) {
        String apkPath = context.getPackageCodePath();
        try {
            byte[] hashed= getDigest(new FileInputStream(apkPath), "SHA-256");
            return Base64.encodeToString(hashed, Base64.DEFAULT);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }

    public static final int BUFFER_SIZE = 2048;

    public static byte[] getDigest(InputStream in, String algorithm) throws Throwable {
        MessageDigest md = MessageDigest.getInstance(algorithm);
        try {
            DigestInputStream dis = new DigestInputStream(in, md);
            byte[] buffer = new byte[BUFFER_SIZE];
            while (dis.read(buffer) != -1) {
            }
            dis.close();
        } finally {
            in.close();
        }
        return md.digest();
    }

首先,感谢您的代码。这个答案在2020年还有效吗? - user2342558
Google Play现在可以优化、重新打包和重新签名上传的.apk文件(并向.apk添加安全元数据),因此这个篡改检查可能已经失效了。 - scottyab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接