Android 应用程序签名:它的工作原理及其重要性

A brass key on a smartphone showing a verified checkmark, illustrating Android app signing

每次您在 Android 手机上安装应用程序时,都会在后台进行无声但关键的安全检查。您的手机会验证APK包的数字签名。这种加密握手可以防止恶意黑客用恶意软件“毒害”您的应用程序,同时确保开发人员可以在不丢失身份的情况下推送更新。

如果您编写应用程序,则只需正确执行签名即可;如果你只是喜欢摆弄 Android,那么它是系统中最容易理解的部分之一。不管怎样,应用程序签名的工作原理 都值得你花时间。下面我们将介绍该技术、签名方案的演变以及如何在线进行 手动验证证书。

您将在本文中学到什么
  • 为什么每个 Android 应用程序都必须签名以及涉及哪些加密技术 (RSA / EC)。
  • v1 (JAR)、v2、v3 和 v4 签名方案之间的区别,以及您的应用程序现在应该使用哪一个。
  • Android 如何根据签名连续性决定是否允许更新。
  • 密钥轮换如何让开发人员在不破坏现有安装的情况下更改其签名密钥。
  • 如何通过命令行或使用我们的 基于浏览器的验证器 自行验证任何 APK 的签名。

什么是应用程序签名?

应用程序签名的核心是开发人员使用 私钥 为其应用程序文件生成签名块的过程。然后将相应的 公钥 嵌入到 META-INF 文件夹内的 APK 中。当您的手机尝试安装该应用程序时,它会使用公钥来检查签名是否与文件内容匹配。

这提供了两个主要属性:

  1. 不变性: 如果应用程序代码的单个字节被更改(例如,被木马更改),签名将不再与文件匹配,Android 将拒绝安装它。
  2. 身份证明: 如果应用程序尝试更新现有应用程序,则它们的签名必须匹配。这就是为什么你不能在官方应用程序上安装被篡改的 Facebook 应用程序。

签名方案的演变

Google不断升级签名机制以提高速度和安全性:

为什么证书对于旁加载很重要

当您从非官方来源下载 APK 时,证书哈希 是您最好的朋友。证书指纹(例如 SHA-256 哈希)唯一标识开发人员的签名密钥。每个应用程序在其所有更新中都保留相同的签名密钥,因此您可以将 APK 的指纹与开发人员发布的值进行比较,以确认其真实性。

如果您怀疑 APK 是假的,您应该通过我们的 在线 APK 验证器 运行它。我们的工具将向您展示:

Android 如何在安装时验证签名

“验证证书”步骤经常被掩盖,因此值得了解一下当您点击 APK 并且 Android 决定是否安装它时操作系统实际执行的操作:

  1. 以 ZIP 格式打开 APK 并找到签名块。 对于 v2/v3 签名,它是紧邻中央目录之前的结构化块;对于旧版 v1 方案,它是 META-INF/*.RSA、*.DSA 或 *.EC 的内容。
  2. 计算 APK 每隔一个字节的 SHA-256 摘要。 签名块被排除在自己的摘要之外;其他所有内容都以定义的块进行散列。
  3. 根据签名块中记录的摘要验证每个块的摘要。 如果自开发人员签署文件以来甚至更改了一个字节,则摘要将不匹配,并且安装将被拒绝,并显示一般的“应用程序未安装”错误。
  4. 验证签名块本身是使用证书的私钥生成的。 证书的公钥用于检查块中的加密签名。成功的检查意味着签署该文件的人拥有与该证书配对的私钥。
  5. 将证书指纹与具有相同软件包名称的任何现有安装进行比较。 如果软件包已安装并且新 APK 使用不同的证书进行签名,则安装将被拒绝,并显示 INSTALL_FAILED_UPDATE_INCOMPATIBLE。这是操作系统的主要反假冒防御:恶意行为者无法用自己的副本替换您的银行应用程序,除非他们还窃取了银行的签名密钥。

这些都不能证明开发人员是值得信赖的,只是您要安装的文件与他们签名的文件在字节上相同,并且没有其他方篡改过它。对开发人员的信任是一项单独的决定,您可以通过决定安装的来源来做出决定。

“签名不匹配”的真正含义是什么

侧面加载时最常见的意外是更新时出现“签名不匹配”错误。这是实际发生的情况:

在实践中,这种情况有两种发生方式:

  1. 第三方 APK 是 真正来自不同的出版商,例如“修改”或“修补”副本。拒绝安装是正确的行为;安装它意味着信任陌生人拥有您银行应用程序已经接触过的相同数据。
  2. 第三方 APK 是 重新上传官方APK,但 Google 的 Play 应用签名系统使用用户的 上传密钥 包装器对每个用户的下载进行签名。对于同一概念应用程序版本,两个设备有时会看到略有不同的签名数据。在这种情况下,根处的证书指纹仍然匹配;您可以通过我们的APK验证器进行验证。

如果证书指纹 确实 与您现有的安装不同,唯一的方法是在旁加载替换之前先卸载当前副本(丢失其数据),切勿禁用签名验证。

生成您自己的签名密钥(针对开发人员)

如果您正在构建 Android 应用程序,您最终需要签署自己的构建版本。使用 Java SDK 中的 keytool 的标准一行命令是:

keytool -genkeypair -v \
        -keystore my-release.keystore \
        -alias my-app -keyalg RSA -keysize 2048 \
        -validity 10000

有两件事需要知道:

对于旁加载测试版本,未签名的调试密钥库就可以了;对于生产,请使用存储在脱机备份中的受密码保护的长期有效密钥库。

像专业人士一样验证应用程序身份

不要相信通用文件名。在几秒钟内检查 APK 的加密核心。

立即验证证书

常见的签名陷阱

  1. 自签名证书: 大多数 Android 应用程序都是自签名的。与网站的 SSL 不同,Android 应用程序签名没有中央机构。您必须直接信任开发商。
  2. 调试证书: 为测试而构建的应用程序使用通用“调试”密钥。这些应用程序永远不应该向公众发布,并且会被许多安全过滤器阻止。
  3. 钥匙丢失: 如果开发人员丢失了他们的私有密钥库,他们可以 绝不 再次更新他们的应用程序。他们必须发布一个具有不同包名称的“新”应用程序。

为您的目标 SDK 选择正确的签名方案

应用程序签名悄然支撑着 Android 的安全性。一旦私钥/公钥关系点击,您就可以判断侧载应用程序的优点,并确认您正在安装的内容自开发人员签名以来没有被更改。有关 Android 内部结构的更多信息,请参阅我们的 XAPK 格式指南。

由 Shaefale 女士设计并记录 首席开发人员和 Android 包架构师 • 在 Android 12–15 上经过验证

Mst Shaefale 在 xapktoapk.com 维护客户端 XAPK/APKS 合并、二进制清单解析器和 APK v1+v2 签名工具。发现过时的命令或操作系统更改?发送编辑说明。