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 的签名工具帮我们"提升了安全性",

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

相关推荐
angushine18 小时前
解决MySQL慢日志输出问题
android·数据库·mysql
fouryears_2341718 小时前
Android 与 Flutter 通信最佳实践 - 以分享功能为例
android·flutter·客户端·dart
成都大菠萝20 小时前
Android ANR
android
Ryan ZHENG21 小时前
[Android][踩坑]Android Studio导入core-libart.jar
android·android studio·jar
q***R30821 小时前
Kotlin注解处理
android·开发语言·kotlin
Digitally21 小时前
如何将文件从三星平板传输到电脑
android
CHINAHEAO21 小时前
Bagisto单独将后台设置成中文
android
E***U94521 小时前
React Native开发
android·react native·react.js
4***99741 天前
Kotlin序列处理
android·开发语言·kotlin
t***D2641 天前
Kotlin在服务端开发中的生态建设
android·开发语言·kotlin