
1. 项目概述为什么你需要关注 apksigner如果你在 Android 开发或逆向安全领域摸爬滚打过一阵子肯定对 APK 签名这个概念不陌生。简单来说签名就是给 APK 文件盖上一个独一无二的“数字公章”用来证明这个应用是谁发布的并且在发布后没有被篡改过。而apksigner就是 Google 官方提供的、目前最推荐也是最强大的 APK 签名和验证工具。它从 Android 7.0API 24开始引入逐步取代了之前开发者们更熟悉的jarsigner工具。为什么说“如何安装 apksigner”这个话题值得单独拿出来聊因为在实际工作中我发现很多朋友尤其是刚入行的开发者对它的理解还停留在“一个命令行工具”的层面。他们可能会在 Android Studio 的构建流程里间接用到它但当需要独立使用、进行自动化脚本签名、或者排查一些棘手的签名问题时就有点抓瞎了。比如你的 CI/CD 流水线需要签名 APK服务器上怎么配置你想验证一个从网上下载的 APK 是否被二次打包过怎么操作这些场景都要求你能独立地、清晰地知道apksigner从哪来、怎么装、怎么用。所以这篇内容不仅仅是告诉你敲哪条命令我会带你从根儿上理解apksigner的来龙去脉搞清楚它和 Android SDK 构建工具的关系然后手把手演示在不同操作系统和环境下的安装与配置方法。更重要的是我会分享一些只有踩过坑才知道的细节比如版本兼容性、环境变量配置的陷阱以及如何验证安装是否真正成功。无论你是 Android 开发者、应用安全研究员还是负责应用分发的运维工程师掌握apksigner的独立安装和使用都是一项非常实用的基本功。2. 核心原理与工具定位apksigner 究竟是什么在直接动手安装之前我们有必要花几分钟搞清楚apksigner到底是什么以及它为什么会出现。这能帮你更好地理解后续的安装路径和配置逻辑避免“知其然不知其所以然”。2.1 从 jarsigner 到 apksigner 的演进在apksigner之前Android 应用主要使用 Java 生态的jarsigner工具进行签名。jarsigner是对整个 JAR 文件进行签名而 APK 本质上就是一种特殊的 JAR 文件。然而Android 系统的签名机制有更复杂的需求V1 签名JAR 签名这是兼容jarsigner的旧方案。它只签名 APK 中的条目文件但不签名整个 APK 文件本身。这导致可以在签名后的 APK 末尾添加额外数据而不破坏签名存在一定的安全风险。V2 签名APK 签名方案 v2从 Android 7.0 开始引入。它是对整个 APK 文件除了签名块本身进行签名任何对 APK 的修改包括在末尾添加数据都会导致签名验证失败安全性大大增强。V3/V4 签名后续引入的更新方案支持密钥轮换和更高效的验证。jarsigner只能生成 V1 签名。为了支持 V2 及更高版本的签名并提供一个专为 APK 格式优化的签名工具Google 开发了apksigner。apksigner的核心职责就是专门处理 Android APK 的签名和验证它支持从 V1 到 V4 的所有签名方案并且其验证逻辑与 Android 设备上的验证逻辑严格保持一致。2.2 apksigner 与 Android SDK 构建工具的关系这是理解安装来源的关键。apksigner并不是一个独立发布的软件包它是Android SDK 构建工具Android SDK Build-Tools的一部分。Android SDK Build-Tools这是一个版本化的组件包含了构建 Android 应用所需的核心工具如aapt资源打包工具、dx/d8/r8DEX 编译器、zipalign对齐优化工具以及我们今天的主角apksigner。版本对应每个版本的 Build-Tools 都包含一个特定版本的apksigner。高版本的apksigner通常支持更多的特性如更新的签名方案和更好的兼容性。Google 建议使用与你的编译目标 SDK 相匹配或更新的 Build-Tools 版本。因此“安装 apksigner” 本质上就是“安装或定位 Android SDK Build-Tools”。你的安装方式取决于你如何管理你的 Android 开发环境。注意有些 Linux 发行版的软件仓库里可能有一个叫apksigner的包但那通常是第三方重新打包的可能与官方版本有差异也可能不包含完整的依赖。对于生产环境或严肃开发强烈建议使用 Android SDK 官方渠道提供的版本。3. 安装路径详解在不同环境下找到 apksigner既然知道apksigner是 Build-Tools 的一部分那么它的具体位置就有规律可循了。下面我们看看在常见的几种环境里它通常藏在哪里。3.1 标准 SDK 管理器安装后的路径如果你通过 Android Studio 的 SDK Manager 或者命令行工具sdkmanager安装了 Build-Tools那么apksigner会出现在以下目录结构中[Android SDK 根目录]/build-tools/[版本号]/例如如果你安装了 Build-Tools 的 34.0.0 版本并且你的 Android SDK 安装在C:\Users\YourName\AppData\Local\Android\SdkWindows 默认或~/Android/SdkmacOS/Linux 默认那么apksigner的完整路径就是Windows:C:\Users\YourName\AppData\Local\Android\Sdk\build-tools\34.0.0\apksigner.batmacOS/Linux:~/Android/Sdk/build-tools/34.0.0/apksigner注意在 Windows 上是一个批处理文件.bat而在 macOS/Linux 上是一个可执行的 shell 脚本。3.2 通过包管理器安装以 macOS 和部分 Linux 为例一些系统包管理器可能提供了apksigner但这通常不是首选方法。macOS (Homebrew): 你可以通过 Homebrew 安装安卓命令行工具套件其中会包含apksigner。brew install android-sdk安装后路径可能在/usr/local/share/android-sdk/build-tools/[版本]/apksigner具体取决于 Homebrew 的配置。但更常见的是它只是帮你安装了sdkmanager你仍然需要通过它来下载具体的 Build-Tools 版本。Linux (apt, yum等): 像 Ubuntu 的apt仓库里可能有android-sdk或apksigner包。同样这些包可能版本陈旧或管理不便。例如在 Ubuntu 上你可以尝试sudo apt update sudo apt install android-sdk但之后很可能还是需要运行sdkmanager来安装特定版本的 Build-Tools。实操心得我强烈建议不要主要依赖系统包管理器来安装apksigner。Android SDK 的版本更新非常频繁而系统仓库的版本往往严重滞后。直接使用 Android 官方的 SDK 管理工具 (sdkmanager) 能让你更灵活地选择和控制所需的版本这也是 Android 开发社区的通用做法。3.3 在 CI/CD 环境中的安装如 GitHub Actions, Jenkins在自动化构建环境中我们通常通过命令行快速安装所需的 Build-Tools。使用 sdkmanager 命令行工具这是最标准的方式。首先确保你有一个 Android SDK 命令行工具Command-line Tools。然后你可以通过以下命令安装特定版本的 Build-Tools# 假设 sdkmanager 在 PATH 中或者你指定了完整路径 # 列出所有可用的包 sdkmanager --list # 安装指定版本的 build-tools例如 34.0.0 sdkmanager build-tools;34.0.0 # 或者安装平台工具和 build-tools sdkmanager platform-tools build-tools;34.0.0安装完成后apksigner就会出现在对应的build-tools/[版本]/目录下。使用第三方 GitHub Action在 GitHub Actions 中你可以使用社区维护的 Action如android-actions/setup-android它会帮你处理好 SDK 和所需组件的安装你只需要指定build-tools-version即可。4. 手把手安装与配置指南理论说完了我们进入实战环节。我会以最通用的方式——使用官方sdkmanager——来演示如何安装apksigner并配置好环境变量。4.1 步骤一获取 Android SDK 命令行工具首先你需要获得 Android SDK 的命令行管理工具sdkmanager。它不依赖于完整的 Android Studio。访问 Android 开发者网站前往 developer.android.com/studio 注意此处仅为说明信息来源实际操作需用户自行访问。下载“Command line tools only”在页面底部找到“命令行工具”部分根据你的操作系统Windows、macOS 或 Linux下载对应的 ZIP 包。例如对于 Linux你可能会下载一个名为commandlinetools-linux-*_latest.zip的文件。解压到合适目录创建一个你喜欢的目录来存放 Android SDK例如~/android-sdk。将下载的 ZIP 包解压到这个目录下。通常解压后会得到一个cmdline-tools文件夹。组织目录结构重要为了让sdkmanager能正常工作需要遵循特定的目录结构。在~/android-sdk目录下创建子目录cmdline-tools然后将解压出来的工具文件夹通常叫latest移动到~/android-sdk/cmdline-tools/latest。最终路径看起来像这样~/android-sdk/cmdline-tools/latest/bin/sdkmanager。4.2 步骤二使用 sdkmanager 安装 Build-Tools现在你可以使用sdkmanager来安装包含apksigner的 Build-Tools 了。打开终端或命令提示符并导航到你的 SDK 目录或者将sdkmanager所在目录加入PATH环境变量。这里我们先直接用完整路径操作。# Linux/macOS 示例 cd ~/android-sdk/cmdline-tools/latest/bin接受许可协议在安装任何组件前你需要接受 Android SDK 的许可协议。可以运行以下命令一次性接受所有许可./sdkmanager --licenses然后一直按y确认所有协议。安装特定版本的 Build-Tools假设我们要安装版本34.0.0。./sdkmanager build-tools;34.0.0sdkmanager会自动下载并将该版本的 Build-Tools 安装到~/android-sdk/build-tools/34.0.0/目录下。apksigner就在这个目录里。4.3 步骤三配置环境变量以便全局调用为了能在任何终端窗口直接输入apksigner命令我们需要把它的路径添加到系统的PATH环境变量中。对于 Linux 和 macOS打开你的 shell 配置文件。通常是~/.bashrc、~/.zshrc或~/.bash_profile。在文件末尾添加以下行请根据你的实际 SDK 路径和使用的 Build-Tools 版本修改export ANDROID_SDK_ROOT$HOME/android-sdk export PATH$PATH:$ANDROID_SDK_ROOT/build-tools/34.0.0ANDROID_SDK_ROOT变量定义了 SDK 的根目录很多工具会用到它。第二行将特定 Build-Tools 版本的路径加入了PATH。保存文件然后让配置生效source ~/.bashrc # 或 source ~/.zshrc对于 Windows在“开始”菜单搜索“环境变量”选择“编辑系统环境变量”。点击“环境变量”按钮。在“系统变量”或“用户变量”部分找到并选中Path变量点击“编辑”。点击“新建”然后添加你的apksigner.bat所在目录的路径例如C:\Users\YourName\AppData\Local\Android\Sdk\build-tools\34.0.0同样你可以新建一个变量ANDROID_SDK_ROOT值为C:\Users\YourName\AppData\Local\Android\Sdk。点击“确定”保存所有更改。你需要重新打开命令提示符或 PowerShell 窗口新的环境变量才会生效。4.4 步骤四验证安装是否成功配置完成后打开一个新的终端或命令提示符窗口输入以下命令进行验证apksigner --version如果安装和配置都正确你会看到类似下面的输出APK Signature Verifier version 4.0这显示了apksigner的版本号证明它已经可以全局调用了。你也可以运行apksigner --help查看所有可用的命令和选项。5. 基础使用与常见操作示例安装好了我们来试试它的基本功能。这里演示两个最核心的操作签名一个 APK 和验证一个 APK 的签名。5.1 使用 apksigner 签名 APK假设你有一个未签名的 APK 文件app-release-unsigned.apk并且你有一个 Java Keystore 文件my-release-key.jks包含私钥和证书。签名命令的基本格式如下apksigner sign --ks [keystore文件] --ks-key-alias [密钥别名] --out [输出文件] [要签名的APK文件]一个具体的例子apksigner sign --ks my-release-key.jks --ks-key-alias my-key-alias --out app-release-signed.apk app-release-unsigned.apk执行这条命令后apksigner会提示你输入 Keystore 的密码和对应密钥的密码如果你设置了的话。输入正确后它就会生成一个已签名的app-release-signed.apk文件。关键参数解析--ks: 指定包含私钥和证书链的 Keystore 文件路径。--ks-key-alias: 指定 Keystore 中用于签名的特定密钥的别名。一个 Keystore 里可以有多对密钥。--out: 指定签名后输出的 APK 文件路径。如果不指定默认会覆盖原文件危险操作不推荐。--v1-signing-enabled/--v2-signing-enabled/--v3-signing-enabled: 可以显式控制启用或禁用某种签名方案。默认情况下apksigner会根据你的密钥和 APK 特性选择最合适的方案组合。5.2 使用 apksigner 验证 APK 签名验证一个 APK 的签名状态非常简单apksigner verify --verbose [要验证的APK文件]例如apksigner verify --verbose app-release-signed.apk--verbose参数会输出详细的验证信息。一个成功的验证输出会包含以下关键信息Verifies Verified using v1 scheme (JAR signing): true Verified using v2 scheme (APK Signature Scheme v2): true Verified using v3 scheme (APK Signature Scheme v3): true Number of signers: 1 Signer #1 certificate DN: CNMy Company, OUAndroid, OMy Org, LCity, STState, CUS Signer #1 certificate SHA-256 digest: a1b2c3d4... Signer #1 certificate SHA-1 digest: e5f6g7h8... Signer #1 key algorithm: RSA Signer #1 key size (bits): 2048 Signer #1 public key SHA-256 digest: i9j0k1l2... ...这个输出告诉你APK 通过了 V1, V2, V3 所有签名方案的验证。只有一个签名者。签名者的证书信息DN。证书和公钥的摘要。密钥算法和长度。如果 APK 被篡改或者签名不完整验证就会失败并输出相应的错误信息。6. 高级配置与疑难排查掌握了基本安装和使用后我们来看看一些更深入的话题和可能遇到的问题。6.1 管理多个 Build-Tools 版本你很可能需要安装多个版本的 Build-Tools 来兼容不同的项目。所有版本都会平行安装在[SDK根目录]/build-tools/下例如build-tools/ ├── 30.0.3/ ├── 33.0.0/ ├── 34.0.0/ └── 35.0.0-rc1/如何指定使用哪个版本通过完整路径调用这是最直接的方式。~/android-sdk/build-tools/34.0.0/apksigner通过环境变量 PATH 的顺序如果你在PATH中添加了多个版本的路径系统会使用第一个找到的。你可以通过调整PATH中路径的顺序来控制默认版本。例如在.bashrc中# 将 34.0.0 放在前面它将成为默认版本 export PATH$HOME/android-sdk/build-tools/34.0.0:$PATH export PATH$PATH:$HOME/android-sdk/build-tools/33.0.0在构建脚本中指定在 Gradle 构建脚本 (build.gradle) 中你可以通过android.buildToolsVersion属性来指定项目使用的 Build-Tools 版本Android Studio 和 Gradle 会据此选择正确的工具路径。6.2 常见问题与解决方案下面是一个快速排查表格列出了安装和使用apksigner时可能遇到的典型问题问题现象可能原因解决方案运行apksigner命令提示“命令未找到”1. Build-Tools 未安装。2. 环境变量PATH未配置或配置错误。3. 配置后未重启终端。1. 使用sdkmanager “build-tools;xx.x.x”安装。2. 检查PATH变量是否包含了apksigner所在的精确目录。在终端输入echo $PATH(Linux/macOS) 或echo %PATH%(Windows) 查看。3. 关闭并重新打开终端或执行source ~/.bashrc。apksigner命令执行报错提示 Java 版本问题apksigner是基于 Java 的工具需要合适的 Java 运行环境 (JRE)。1. 确保系统已安装 Java。在终端运行java -version检查。2.apksigner需要 Java 8 或更高版本。如果版本过低请升级 JDK/JRE。3. 如果安装了多个 Java 版本请确保JAVA_HOME环境变量指向了正确的版本。签名时提示 “Keystore was tampered with, or password was incorrect”密钥库密码错误或者密钥库文件已损坏。1.仔细核对密码注意大小写和特殊字符。2. 确认你使用的--ks-key-alias别名在 Keystore 中存在。3. 如果密码遗忘几乎无法找回。请务必妥善保管 Keystore 文件和密码。验证 APK 时提示 “DOES NOT VERIFY”APK 文件损坏、签名被破坏、或者使用了不支持的签名方案。1. 重新下载或获取 APK 文件。2. 确认 APK 是否真的被正确签名。可以用apksigner verify –verbose查看具体哪个方案验证失败。3. 对于非常古老的 APK仅 V1 签名确保你的apksigner版本支持。sdkmanager运行非常慢或无法下载网络连接问题或者 SDK 仓库镜像未配置。1. 检查网络连接。2. 对于国内用户可以配置国内镜像源加速。在~/.android/目录下创建或修改repositories.cfg文件或通过设置HTTP_PROXY/HTTPS_PROXY环境变量使用代理。6.3 关于签名密钥和 Keystore 的安全提醒这部分虽然不完全属于“安装”范畴但和apksigner的使用息息相关且至关重要。备份备份备份你的发布 Keystore 文件 (.jks或.keystore) 和密码是应用更新的唯一凭证。一旦丢失你将永远无法为同一个应用包名发布更新。必须将其在多个安全位置备份。不要在版本控制系统中提交 Keystore千万不要将包含私钥的 Keystore 文件提交到 Git 等版本控制系统。应该通过环境变量或独立的配置文件不提交来在构建脚本中引用它。使用不同的密钥为调试版本和发布版本使用不同的 Keystore。调试密钥通常由 Android SDK 自动生成安全性低仅用于开发测试。考虑密钥轮换 (Key Rotation)从 Android 9 (API 28) 开始支持的 V3 签名方案允许在不影响应用更新的情况下更换签名密钥。这为长期项目提供了更好的安全弹性。apksigner支持 V3 签名为未来可能的密钥轮换留下了可能性。7. 集成到自动化流程与最佳实践对于个人开发者手动签名或许可行。但对于团队或持续集成自动化是必须的。7.1 在 Gradle 构建脚本中配置签名这是 Android 开发中最常见的方式。在模块级的build.gradle.kts(Kotlin DSL) 或build.gradle(Groovy) 中配置signingConfigsGroovy 示例android { signingConfigs { release { storeFile file(path/to/your/keystore.jks) storePassword System.getenv(STORE_PASSWORD) keyAlias System.getenv(KEY_ALIAS) keyPassword System.getenv(KEY_PASSWORD) } } buildTypes { release { signingConfig signingConfigs.release // ... 其他配置 } } }这里通过System.getenv()从环境变量读取密码避免了将敏感信息硬编码在脚本中。7.2 在 CI/CD 流水线中使用在 Jenkins、GitHub Actions、GitLab CI 等环境中步骤通常是安装 Android SDK 和指定版本的 Build-Tools使用本文介绍的方法。将签名 Keystore 文件作为安全变量或机密文件注入到构建环境。设置对应的密码环境变量如STORE_PASSWORD,KEY_PASSWORD。运行 Gradle 的assembleRelease任务Gradle 会自动调用apksigner完成签名。GitHub Actions 片段示例jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Set up JDK uses: actions/setup-javav4 with: distribution: temurin java-version: 17 - name: Setup Android SDK uses: android-actions/setup-androidv3 - name: Build Release APK run: ./gradlew assembleRelease env: STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} - name: Upload APK Artifact uses: actions/upload-artifactv4 with: name: app-release path: app/build/outputs/apk/release/*.apk7.3 最佳实践总结版本固定在团队项目和 CI 中明确指定buildToolsVersion避免因不同机器默认版本不同导致构建差异。环境隔离签名密钥和密码绝不入库通过 CI 系统的秘密管理功能传递。验证产出在 CI 流程的最后可以增加一个步骤用apksigner verify对产出的 APK 进行校验确保签名过程没有出错。保持更新定期检查并更新 Android SDK Command-line Tools 和 Build-Tools以获取最新的安全补丁和功能改进但升级前需在测试环境中验证兼容性。安装apksigner本身只是一个起点真正掌握它在于理解其在 Android 应用生命周期中的关键作用并能够熟练地将其集成到你的开发和发布工作流中。从手动命令行操作到全自动 CI/CD 集成这个工具贯穿始终是保障应用完整性和开发者身份真实性的基石。希望这篇详细的指南能帮你扫清障碍更自信地处理 APK 签名相关的一切任务。如果在实际操作中遇到本篇未覆盖的特定问题多查阅apksigner --help的输出和官方文档结合具体的错误信息进行搜索大部分问题都能找到解决方案。