You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时编程计算APK校验和(适配API28-33、Gradle6.6.1)

运行时计算APK校验和实现防篡改方案(适配minSdk28+)

问题分析

你之前使用applicationInfo.publicSourceDir计算校验和不准确,核心原因是:

  • 若应用通过App Bundle(AAB)分发,该路径指向拆分后的base.apk,不包含动态模块或后续更新的资源;
  • 部分场景下该路径可能指向系统缓存的APK副本,而非实际安装的完整APK文件,导致资源修改后校验和未变化。

可行实现方案

针对你的环境(minSdkVersion=28,targetSdkVersion=33),以下是可靠的实现步骤:

1. 正确获取APK完整路径

使用PackageInfo.applicationInfo.sourceDir获取主APK文件路径,该路径在minSdk28+下会指向包含应用核心代码、资源的完整APK文件,无论是否为AAB分发的拆分包,修改资源后文件内容会同步变化。

2. 实现APK文件哈希计算

推荐使用SHA-256算法(安全性高于MD5)计算文件校验和,以下是Kotlin实现代码:

import java.io.FileInputStream
import java.security.MessageDigest

object ChecksumUtils {
    fun calculateApkSha256(filePath: String): String? {
        return try {
            val digest = MessageDigest.getInstance("SHA-256")
            FileInputStream(filePath).use { inputStream ->
                val buffer = ByteArray(8192)
                var readBytes = inputStream.read(buffer)
                while (readBytes != -1) {
                    digest.update(buffer, 0, readBytes)
                    readBytes = inputStream.read(buffer)
                }
            }
            val hashBytes = digest.digest()
            // 转换为十六进制字符串
            hashBytes.joinToString("") { "%02x".format(it) }
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
}

3. 在应用中调用校验逻辑

在Activity或Context中获取APK路径并计算校验和:

val packageInfo = packageManager.getPackageInfo(packageName, 0)
val apkFilePath = packageInfo.applicationInfo.sourceDir
val validChecksum = getValidChecksumFromServer() // 从后端获取合法校验和
val currentChecksum = ChecksumUtils.calculateApkSha256(apkFilePath)

if (currentChecksum == validChecksum) {
    // 校验通过,正常启动应用
} else {
    // 校验失败,触发防篡改逻辑(如退出应用、上报服务器)
}

关键注意事项

  • 权限处理:minSdk28+(含Android 10+)中,应用读取自身安装目录下的APK文件无需申请READ_EXTERNAL_STORAGE权限,系统默认允许。
  • 校验和存储:禁止将合法校验和硬编码在APK中,必须通过后端服务器实时获取;无网络场景可将校验和的二次哈希值存储在JNI层,增加篡改难度。
  • 代码混淆:确保校验逻辑不被反编译篡改,在ProGuard规则中添加:
    -keep class com.yourpackage.utils.ChecksumUtils {
        public static java.lang.String calculateApkSha256(java.lang.String);
    }
    
  • 反Hook防护:攻击者可能通过Xposed/Frida Hook校验方法返回假结果,可在校验逻辑中加入反Hook检测(如检测调试器、异常进程),或直接将校验逻辑移至Native层实现。

验证方法

修改APK中的资源文件(如替换drawable下的图片),重新签名安装后,运行应用计算校验和,结果应与原APK的校验和完全不同。

内容的提问来源于stack exchange,提问作者kaveri kataraki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:45:25