Android 稀奇古怪系列:新版本签名问题-Algorithm HmacPBESHA256 not available

🧩 Android 稀奇古怪系列:Algorithm HmacPBESHA256 not available

做 Android 开发久了,总会遇到些"不按常理出牌"的 BUG。

它们不是语法错误,而是藏在系统兼容、JDK 差异、Gradle 工具链甚至 IDE 默认行为里的暗坑。

这一回的坑,是由 Android Studio 自带签名工具的"安全性提升" 引发的兼容灾难。


🚨 异常概述

报错信息:

vbnet 复制代码
com.android.ide.common.signing.KeytoolException:
Failed to read key Key0 from store "C:\work\Android\xxx\app\test.jks":
Integrity check failed: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available

场景非常常见:

  • 新版本 Android Studio(内置 JDK 21) 中使用
    「Generate Signed Bundle / APK」生成签名;
  • 拿这个签名文件放到老项目(JDK 11 环境)编译;
  • 构建直接报错。

🧱 环境信息

项目 版本
Android Studio Meerkat Feature Drop · 2024.3.2
内置 JDK 21
本地构建 JDK 11
Gradle 版本 7.3.1

🔍 BUG 原因分析

1. 什么是 HmacPBESHA256?

HmacPBESHA256 是一种 keystore 加密算法,

全称是 HMAC-based Password-Based Encryption with SHA-256

它结合了:

  • HMAC-SHA256:基于 SHA-256 的消息认证;
  • PBKDF2:通过多次哈希迭代生成强密钥。

作用是将用户输入的密码转化为高强度密钥,用来保护 .jks / .p12 文件内部的私钥内容。


2. 真正的问题不是 JDK,而是 Android Studio 的签名向导

许多人以为"JDK 21 生成的签名不兼容",其实不准确。
高版本 JDK 完全可以生成兼容签名。

问题的根源在于------Android Studio 自带的签名向导使用了新的默认算法。

区别如下:

生成方式 使用算法 是否兼容旧版 JDK
Android Studio 签名向导(JDK 21 内置 keytool) HmacPBESHA256 ❌ 否
命令行 keytool(即使是 JDK 21) PBEWithMD5AndDES ✅ 是
旧版 keystore 文件 旧算法 ✅ 是

也就是说:

坑不在 JDK 版本,而在 Android Studio 的签名工具默认启用了新算法。


3. 异常流程复盘

markdown 复制代码
Android Studio 2024.3.2(内置 JDK 21)
    ↓
Generate Signed Bundle / APK
    ↓
生成 keystore(HmacPBESHA256)
    ↓
旧项目使用 JDK 11 读取
    ↓
JDK 11 不识别该算法
    ↓
java.security.NoSuchAlgorithmException

🧩 解决方案

✅ 方案一:统一升级构建环境(推荐)

将项目构建使用的 JDK 升级到 14 及以上版本

因为从 JDK 14 起,HmacPBESHA256 算法已被原生支持。

检查版本
复制代码
java -version
在 Gradle 中指定 JDK

gradle.properties 添加:

ini 复制代码
org.gradle.java.home=C:\Program Files\Java\jdk-17

或直接在 Android Studio 里:
File > Settings > Build, Execution, Deployment > Build Tools > Gradle > Gradle JDK

中统一设置。

确保 IDE、Gradle、命令行、CI/CD 环境的 JDK 全部一致。


✅ 方案二:使用命令行生成签名(避免新算法)

如果暂时不能升级 JDK,可以直接用命令行生成签名文件。

命令行的 keytool 即使在 JDK 21 下,也不会自动启用 HmacPBESHA256

示例命令:

bash 复制代码
keytool -genkeypair -alias testKey \
  -keyalg RSA -keysize 2048 -validity 36500 \
  -keystore test_compatible.jks \
  -storetype JKS \
  -storepass 123456 \
  -keypass 123456 \
  -dname "CN=Test, OU=Dev, O=Company, L=City, S=State, C=CN"

这样生成的 keystore 使用传统算法(PBEWithMD5AndDES),

兼容所有 JDK 版本和老项目环境。


💡 延伸思考

Android Studio 自带的 JetBrains Runtime (JBR) 与系统 JDK 是两套独立环境。

自从 Arctic Fox 之后,AS 默认启用了自己的内置 JDK。

结果就是:

  • 签名时走了 JBR 的 keytool;
  • 编译时走了本地的 JDK;
  • 两者算法不一致,冲突爆发。

🧭 总结

问题点 结论
错误原因 Android Studio 签名向导默认使用新算法 HmacPBESHA256
根本原因 低版本 JDK(≤11)不支持该算法
解决方案 1 升级项目 JDK ≥14
解决方案 2 用命令行 keytool 生成签名
建议 统一 IDE 与构建环境 JDK 版本,避免混用

有时候,坑并不是因为"版本太高",

而是因为"工具太聪明"。

Android Studio 的签名工具帮我们"提升了安全性",

也顺便帮我们"挖了个坑"。

相关推荐
叶羽西3 分钟前
Android15跟踪函数调用关系
android
消失的旧时光-19432 小时前
webView 的canGoBack/goBack 回退栈
android·webview
SHEN_ZIYUAN2 小时前
Flow 责任链模式图解
android
沐怡旸4 小时前
【底层机制】LeakCanary深度解析:从对象监控到内存泄漏分析的完整技术体系
android·面试
又菜又爱coding4 小时前
Android + Flutter打包出来的APK体积太大
android·flutter
LiuYaoheng4 小时前
【Android】Drawable 基础
android·java
Jerry6 小时前
构建 Compose 界面
android
Y多了个想法6 小时前
Linux驱动开发与Android驱动开发
android·linux·驱动开发
2501_916007478 小时前
从零开始学习iOS App开发:Xcode、Swift和发布到App Store完整教程
android·学习·ios·小程序·uni-app·iphone·xcode
姝然_95278 小时前
ConstraintLayout属性详解
android