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

Android如何通过包名编程获取已安装APK的SHA256摘要

通过包名获取已安装APK SHA256摘要的实现方法

核心逻辑:先通过包名定位到设备上对应APK的实际存储路径,再通过系统接口或官方签名工具提取签名证书的SHA256值,结果和手动执行apksigner verify --print-certs的输出完全一致。

方案1:Android设备端原生实现(在设备上运行的APP内调用)

该方案不需要依赖PC端工具,不需要root权限,普通应用即可调用。

  1. 先配置清单文件权限和包查询规则
    Android 11及以上系统限制了应用对其他已安装APP的查询权限,需要在AndroidManifest.xml中添加如下配置:
    <!-- 可选:如果需要查询所有应用可保留该权限,仅查询指定包可省略 -->
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
    <!-- Android 11+ 必须添加要查询的包声明 -->
    <queries>
        <package android:name="填入你要查询的目标包名" />
    </queries>
    
  2. 核心实现代码(Java为例)
    import android.content.Context;
    import android.content.pm.ApplicationInfo;
    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 java.security.MessageDigest;
    
    public class ApkSignUtil {
        public static String getInstalledApkSHA256(Context context, String packageName) throws Exception {
            PackageManager pm = context.getPackageManager();
            // 校验应用是否安装,同时获取APK路径
            ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
    
            // 兼容不同版本系统获取签名数组
            Signature[] signatures;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                PackageInfo pkgInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES);
                SigningInfo signingInfo = pkgInfo.signingInfo;
                // 自动兼容V1/V2/V3签名方案,取第一个签名证书即可,多证书场景可遍历数组
                signatures = signingInfo.getApkContentsSigners();
            } else {
                PackageInfo pkgInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
                signatures = pkgInfo.signatures;
            }
            if (signatures == null || signatures.length == 0) {
                throw new RuntimeException("无法获取目标应用的签名信息");
            }
            byte[] certBytes = signatures[0].toByteArray();
    
            // 计算证书的SHA256摘要
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] digest = md.digest(certBytes);
    
            // 格式化为和apksigner输出一致的大写十六进制、冒号分隔格式
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < digest.length; i++) {
                String hex = Integer.toHexString(0xff & digest[i]);
                if (hex.length() == 1) sb.append('0');
                sb.append(hex.toUpperCase());
                if (i != digest.length - 1) sb.append(':');
            }
            return sb.toString();
        }
    }
    

方案2:PC端编程实现(通过ADB连接设备调用,无需在设备上安装额外APP)

该方案不需要给设备装应用,只要开启ADB调试即可,不需要root权限。
核心流程:先通过ADB命令查询对应包名的APK存储路径,再拉取APK到本地临时目录,调用官方apksigner工具提取SHA256即可,Python示例代码如下:

import subprocess
import re
import os

def get_apk_sha256_by_pkg(pkg_name: str) -> str:
    # 查询设备上对应包名的APK路径
    path_proc = subprocess.run(
        ["adb", "shell", "pm", "path", pkg_name],
        capture_output=True, text=True
    )
    path_res = path_proc.stdout.strip()
    if not path_res.startswith("package:"):
        raise RuntimeError(f"设备上未找到包名为{pkg_name}的应用")
    device_apk_path = path_res.removeprefix("package:")

    # 拉取APK到本地临时目录
    tmp_apk_path = f"/tmp/tmp_{pkg_name}.apk"
    subprocess.run(
        ["adb", "pull", device_apk_path, tmp_apk_path],
        capture_output=True, check=True
    )

    try:
        # 调用apksigner获取证书信息
        sign_proc = subprocess.run(
            ["apksigner", "verify", "--print-certs", tmp_apk_path],
            capture_output=True, text=True, check=True
        )
        # 正则提取SHA256摘要
        match = re.search(r"SHA-256 digest:\s*([0-9A-F:]+)", sign_proc.stdout)
        if not match:
            raise RuntimeError("提取SHA256摘要失败")
        return match.group(1)
    finally:
        # 清理临时文件
        if os.path.exists(tmp_apk_path):
            os.remove(tmp_apk_path)

注意事项

  • 采用Split APK分包机制的应用(按架构、资源拆分多个APK),不需要遍历所有分包文件,主包(base.apk)的签名和所有分包完全一致,直接读取主包签名即可。
  • 不要自行实现APK签名块解析逻辑,系统PackageManager接口和官方apksigner工具已经兼容所有历史和新增的签名方案(V1/V2/V3/V4),自行解析容易出现版本兼容问题。
  • *禁止使用仅读取JAR签名(V1)的老旧工具类计算摘要,在应用仅使用V2+签名的场景下会获取到错误结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:57:11