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

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

相关推荐
catchadmin2 分钟前
PHP 现在可以零成本构建原生 iOS 和 Android 应用 NativePHP for Mobile v3 发布
android·ios·php
独自破碎E12 分钟前
【回溯】二叉树的所有路径
android·java
安卓机器14 分钟前
安卓玩机工具推荐------免root权限使用的 支持安卓4至安卓16系统的系统开源应用 推荐
android·反编译apk
summerkissyou198715 分钟前
android-蓝牙-广播启动-startAdvertising和startAdvertisingSet区别
android·蓝牙
雪球Snowball20 分钟前
【Android关键流程】Configuration变更时更新应用程序配置
android
h7ml20 分钟前
于 CompletableFuture 的异步编排优化企业微信通知发送性能
android·windows·企业微信
子木鑫23 分钟前
[SUCTF 2019] CheckIn1 — 利用 .user.ini 与图片马构造 PHP 后门并绕过上传检测
android·开发语言·安全·php
风清云淡_A25 分钟前
【ANDROID】使用webview实现加载第三方的网页效果
android
吴声子夜歌33 分钟前
RxJava——操作符详解(四)
android·echarts·rxjava
我是阿亮啊1 小时前
Android Handler 消息机制之 Looper 深度解析
android·loop·handler·looper