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

如何获取APK签名?Android新手求助Java实现问题

获取已安装APK签名的正确方法

你的代码存在几个关键问题,导致无法正常获取有效签名:

  1. PackageManager.GET_SIGNATURES 从Android 9(API 28)开始已被弃用,高版本系统中使用它可能无法正确获取签名信息
  2. signatures[0].toString() 返回的是Signature对象的默认字符串(格式类似android.content.pm.Signature@xxxx),并非实际的签名哈希值
  3. Android 11及以上系统需要额外权限才能查询其他应用的信息

以下是兼容各版本的正确实现:

1. 配置权限

在AndroidManifest.xml中添加对应权限:

  • 如果是Android 11(API 30)及以上,需要添加全局查询权限(或仅声明需要查询的特定包):
<!-- 全局查询权限,可忽略lint警告 -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
    tools:ignore="QueryAllPackagesPermission" />

<!-- 或者仅声明需要查询的特定包,更合规 -->
<queries>
    <package android:name="com.example.targetapp" /> <!-- 替换为目标包名 -->
</queries>
  • 低版本系统无需额外权限

2. 核心实现代码

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.os.Build;
import android.util.Log;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SignatureUtils {
    // 获取指定应用的签名哈希(默认SHA-1,可替换为SHA-256)
    public static String getAppSignatureHash(PackageManager packageManager, String packageName) {
        try {
            Signature[] signatures;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                // API 28及以上使用新的SigningInfo API
                SigningInfo signingInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo;
                // 判断是否有多个签名者,优先取APK内容签名者
                signatures = signingInfo.hasMultipleSigners() 
                    ? signingInfo.getApkContentsSigners() 
                    : signingInfo.getSigningCertificateHistory();
            } else {
                // 低版本使用旧API
                PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
                signatures = packageInfo.signatures;
            }

            if (signatures == null || signatures.length == 0) {
                Log.e("SignatureUtils", "未获取到签名信息");
                return null;
            }

            // 将Signature转换为可读的哈希字符串(这里用SHA-1,可换成SHA-256)
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(signatures[0].toByteArray());
            StringBuilder hexBuilder = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) {
                    hexBuilder.append('0');
                }
                hexBuilder.append(hex);
            }
            return hexBuilder.toString().toUpperCase();

        } catch (PackageManager.NameNotFoundException e) {
            Log.e("SignatureUtils", "包名不存在:" + e.getMessage());
            return null;
        } catch (NoSuchAlgorithmException e) {
            Log.e("SignatureUtils", "哈希算法不存在:" + e.getMessage());
            return null;
        }
    }
}

3. 在Activity中调用

// 替换为目标应用的包名
String targetPackage = "com.example.targetapp";
String signatureHash = SignatureUtils.getAppSignatureHash(getPackageManager(), targetPackage);

if (signatureHash != null) {
    sig.setText(signatureHash);
} else {
    sig.setText("获取签名失败");
}

关键说明

  • 优先使用SigningInfo API适配高版本系统,避免因旧API弃用导致的兼容性问题
  • 转换为哈希字符串才是实际可用的签名标识(比如用于第三方平台校验),而非直接使用Signature的toString()结果
  • 根据需求选择哈希算法,常见的有SHA-1和SHA-256,大部分第三方平台会指定使用哪种

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:10:34