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

基于Flutter通过签名检测应用篡改:Play Store签名不一致求助

问题描述

本地分发的生产构建版本中,应用篡改检测代码运行正常,但上传至Play Store后获取到的应用签名与预期不一致。

使用的代码片段:

//get the current app signature
public static String getCurrentAppSignature(Context context) throws PackageManager.NameNotFoundException, NoSuchAlgorithmException {
  PackageManager packageManager = context.getPackageManager();
  PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
  // Get the first signature from the package info.
  Signature signature = packageInfo.signatures[0];
  // Get the SHA-1 hash of the signature.
  byte[] sha1 = getSHA1(signature.toByteArray());
  // Convert the SHA-1 hash to a string.
  String sha1String = convertToHexString(sha1);
  return sha1String;
}

//get the SHA1 hash
private static byte[] getSHA1(byte[] data) throws NoSuchAlgorithmException {
  MessageDigest digest = MessageDigest.getInstance("SHA-1");
  digest.update(data);
  return digest.digest();
}

//convert to HexString
private static String convertToHexString(byte[] data) {
  StringBuilder sb = new StringBuilder();
  for (byte b : data) {
    sb.append(String.format("%02x", b));
  }
  return sb.toString();
}
解决方案

核心原因

启用App Signing by Google Play后,Play Store会使用Google管理的分发密钥重新签名你的应用。本地构建时用的是你自己的上传密钥签名,而用户从Play Store下载的应用是分发密钥签名的,两者哈希值自然不同。

具体修复步骤

  1. 获取分发签名的SHA-1值
    登录Google Play Console,进入你的应用 > 应用签名 > 复制"应用签名证书"下的SHA-1值,替换代码中用于校验的预期签名值。

  2. 替换废弃API并兼容多版本
    PackageManager.GET_SIGNATURES在Android 9(API 28)已被废弃,无法正确获取高版本系统的签名信息,需改用GET_SIGNING_CERTIFICATES,同时兼容低版本:

    public static String getCurrentAppSignature(Context context) throws PackageManager.NameNotFoundException, NoSuchAlgorithmException {
        PackageManager packageManager = context.getPackageManager();
        String packageName = context.getPackageName();
        int flags = PackageManager.GET_SIGNING_CERTIFICATES;
    
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            flags = PackageManager.GET_SIGNATURES;
        }
    
        PackageInfo packageInfo = packageManager.getPackageInfo(packageName, flags);
    
        Signature[] signatures;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            SigningInfo signingInfo = packageInfo.signingInfo;
            // 处理多签名场景,优先取APK内容签名者
            signatures = signingInfo.hasMultipleSigners() 
                ? signingInfo.getApkContentsSigners() 
                : signingInfo.getSigningCertificateHistory();
        } else {
            signatures = packageInfo.signatures;
        }
    
        // 遍历所有签名,避免遗漏合法签名
        for (Signature signature : signatures) {
            byte[] sha1 = getSHA1(signature.toByteArray());
            String sha1String = convertToHexString(sha1);
            return sha1String;
        }
        return null;
    }
    
  3. 多签名校验逻辑优化
    如果应用存在多签名(比如同时配置了上传密钥和分发密钥),需修改校验逻辑:遍历所有获取到的签名,只要与预先存储的任意一个合法签名匹配,就判定为未篡改。

  4. 签名值安全存储
    不要将合法签名值直接硬编码在代码中,建议存储在加密的assets文件、安全存储服务或后端接口中,降低被逆向篡改的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:17:03