Vibeloy
注册
全部文章

博客

如何获取 SHA-1 和 SHA-256 指纹(keytool、Firebase)

发布日期: 更新日期: 阅读约 7 分钟

什么是 SHA-1/SHA-256 指纹?在哪里需要用到它?

指纹是从签署你应用的证书中派生出的哈希值;它证明了某个软件包是由哪张证书生成的。一个 Android 应用的每个 keystore/alias 组合都会生成自己独特的指纹——同一个应用用不同的 keystore 签名会得到不同的 SHA-1。

这个值最常见于三个地方需要用到:在 Firebase 控制台添加 Android 应用时(用于 Google Sign-In、Phone Authentication、App Check 等功能),在 Google Cloud Console 中按包名 + SHA-1 限制 Maps SDK for Android API 密钥时,以及在你服务器上托管、用于 Android App Links 自动验证的 assetlinks.json 文件中。

长期以来,SHA-1 一直用于经典场景,如 Google Sign-In 和 Maps API 密钥限制;SHA-256 则是 App Links 验证(assetlinks.json)和一些较新的 Firebase 功能所必需的。keytool -list -v 命令会在同一次输出中打印出两者,因此无论要求的是哪一个,一条命令就够了。

从 debug keystore 获取 SHA

Android Studio 和 Flutter 会为本地开发自动生成一个 debug keystore,并带有固定的信息:在 macOS/Linux 上位于 ~/.android/debug.keystore,在 Windows 上位于 C:\Users\<你的用户名>\.android\debug.keystore;alias 始终是 androiddebugkey,store 密码和 key 密码都是 android。

有了这些信息,命令就是:keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android。输出会显示"SHA1:"和"SHA256:"这两行,均以冒号分隔的十六进制对形式呈现。

此指纹仅适用于 debug 构建;debug keystore 同时也是机器特定的——每位开发者和每台 CI 机器各自的 debug.keystore 都会生成不同的 SHA-1。如果你是团队协作,每个成员(以及 CI)都需要分别把自己的 debug SHA-1 添加到 Firebase 中;这是"Google Sign-In 在我这边能用,但队友那边不行"这类问题最常见的原因。

从 release/upload keystore 获取 SHA

如果你已经有一个 release 或 upload keystore(我们在另一篇指南中介绍了如何用 keytool 创建它),命令的形式相同——只需指向你自己的文件和 alias:keytool -list -v -keystore /path/to/your/upload-keystore.jks -alias upload。它会提示你输入创建 keystore 时设置的 store 密码。

你可以从 android/key.properties 文件中读取这些信息(storeFile、keyAlias);在提示时交互式地输入密码,而不是把它写在命令行里,可以避免密码以明文形式留在你的 shell 历史记录中。

由此生成的 SHA-1/SHA-256 属于你的"upload key"。如果你的应用启用了 Play App Signing(自 2021 年起新应用强制要求),该值可能与分发给用户的软件包的实际签名不一致——下一节将讨论这一点。

Play App Signing 下:debug 与 upload 与 app signing key 的区别(头号常见错误)

启用 Play App Signing 后,你用自己的 upload key 签署 AAB,但 Google Play 在将软件包分发给用户之前会用它自己的"app signing key"重新签名。结果就是:用户从商店下载的实际应用上的证书,与你从本地 upload keystore 提取的 SHA-1 并不匹配。

这正是最常见的错误:开发者把本地 upload keystore 中的 SHA-1 添加到 Firebase,在自己的设备和内部测试版本上一切正常,但对于从 Play Store 下载应用的真实用户来说,Google Sign-In 或 Maps API 会悄无声息地失败——因为商店中的软件包携带的是不同的证书。

从 Play Console 的 Protected with Play > Play Store protection > Manage Play app signing 界面获取正确的值,这里列出了两个独立的证书:"App signing key certificate"(用户收到的真实签名)和"Upload key certificate"。这个界面上会分别列出各自的 SHA-1、SHA-256 和 MD5 值。

实用的修复方法:Firebase 允许你为每个 Android 应用注册多个指纹。同时添加 debug keystore 的 SHA-1、upload key 的 SHA-1,以及 app signing key 的 SHA-1;这样一来,本地开发、直接以 APK 形式分发的内部测试版本,以及从 Play Store 真实安装的用户,都能正确通过身份验证。

将 SHA 指纹添加到 Firebase

前往 Firebase Console > Project settings(齿轮图标)>"Your apps",找到你的 Android 应用卡片,在"SHA certificate fingerprints"字段中添加 keytool 输出中的 SHA-1 或 SHA-256 值,然后保存。你可以为同一个应用卡片添加任意多个指纹。

粘贴时,请按 keytool 输出的原样精确复制(冒号分隔的十六进制对);Firebase 接受带冒号或不带冒号的值,但手动重新输入容易出现转录错误。对于像 Google Sign-In 或 App Check 这类依赖 SHA 的功能,建议在添加指纹后重新下载更新后的 google-services.json 文件并放回项目中。

由于 Vibeloy Keystore 保险库以端到端加密方式存储你的 keystore 文件和密码,你可以直接从保险库中一键查看并复制 SHA-1/SHA-256 值,而不必每次使用 keytool 时都去查找文件路径和密码。这是 Vibeloy 的高级(premium)功能。

常见问题

为什么我的 debug 和 release SHA-1 值不同?
因为它们来自不同的 keystore。debug keystore 是自动生成的、与机器绑定的,而 release/upload keystore 则是你自己创建的永久密钥。它们的指纹不同是正常的;你需要将两者分别添加到 Firebase 中。
我应该使用 SHA-1 还是 SHA-256?
使用你正在集成的功能所要求的那一个;如果不确定,两个都添加。keytool -list -v 命令已经在同一次输出中打印了两者,因此不需要为每一个单独运行一次命令。
在 Play App Signing 下,我应该往 Firebase 添加哪个 SHA?
同时添加你的 upload key 的 SHA 和 app signing key 的 SHA——你可以从 Play Console 的 Protected with Play > Play Store protection > Manage Play app signing 界面获取这两个值。只添加本地 upload keystore 中的值,会导致该功能对从 Play Store 下载的真实用户失效。
运行 keytool 时出现"command not found"错误,该怎么办?
keytool 随 JDK 一起提供,如果不在你的 PATH 中就无法直接找到它。在 macOS/Linux 上,JDK 通常已经在 PATH 中;如果没有,请指向 Android Studio 安装的 JDK 的 bin 目录。在 Windows 上,最可靠的方法是运行 flutter doctor -v,在输出中找到"Java binary at:"这一行,从而定位该 JDK 的 bin 目录;直接假设路径是"%JAVA_HOME%\bin\keytool"在该变量未设置或安装了多个 JDK 时可能会产生误导。
添加到 Firebase 的指纹要多久才会生效?
通常几分钟内就会生效。对于像 Google Sign-In 或 App Check 这样的一些功能,添加后你可能需要重新下载更新后的 google-services.json 文件并放回项目中;否则旧文件将无法识别新指纹。