2. 密钥生成环境准备:最低 API 等级、依赖声明、Provider 选择
在 Android 平台上使用 Keystore 生成 RSA 密钥对,首先需要确认项目环境和编译配置满足最低 API 等级要求、正确声明依赖项,并选用合适的 Provider。这三项准备工作直接决定了密钥的安全级别、可用性以及兼容性。以下从原理到实操逐一展开。
2.1 最低 API 等级要求
Android Keystore 系统自 API 18(Android 4.3)引入,但仅支持对称密钥和 RSA 密钥对的生成与导入。真正支持 非对称密钥在硬件安全模块(HSM/TEE)中生成且私钥不可导出 的功能从 API 23(Android 6.0)开始,通过 AndroidKeyStore Provider 实现。不同 API 等级的能力差异如下表所示:
| API 等级(Android 版本) | 密钥生成能力 | 私钥不可导出 | 硬件安全支持 | 推荐用途 |
|---|---|---|---|---|
| API 18 – 22 (4.3 – 5.1) | RSA 密钥对生成,存储于软件 Keystore | 部分(软件隔离,可导出) | 不支持 | 低安全场景,仅用于测试 |
| API 23+ (6.0+) | RSA 密钥对生成,AndroidKeyStore Provider |
✅ 私钥无法离开安全环境 | 支持(TEE/StrongBox) | 生产环境首选 |
| API 28+ (9.0+) | 支持 StrongBox Keymaster(独立安全芯片) | ✅ 硬件级防提取 | 专用芯片 | 金融、支付等高敏场景 |
minSdkVersion 设为 23 以确保所有设备都能使用 AndroidKeyStore 的硬件安全特性。若必须支持更低版本,应在运行时判断并降级为软件 Keystore——但这会严重降低私钥安全性。
2.2 依赖声明(build.gradle)
主项目无需任何额外依赖即可使用 android.security.keystore 包,因为 Android SDK 内置了 Keystore API。但若希望使用 AndroidX Security Library 提供的加密工具类(如 MasterKey 简化 AES 加密),则需在 build.gradle 中添加:
dependencies {
// 可选:提供更高层加密 API,自动处理 Provider 选择
implementation "androidx.security:security-crypto:1.1.0-alpha06"
// 若使用 Kotlin 协程加密扩展(非必需)
implementation "androidx.security:security-crypto-ktx:1.1.0-alpha06"
}
注意:security-crypto 依赖会自动引入 AndroidKeyStore Provider,并封装了密钥生成、加密解密的常见模式。如果仅需 RSA 裸密钥对操作,可以不添加此库,直接使用 KeyPairGenerator API。
2.3 Provider 选择:AndroidKeyStore 与其他
Java Cryptography Architecture(JCA)允许多个 Provider 实现。对于 Android Keystore,必须明确指定 Provider 为 "AndroidKeyStore",否则默认会使用 Bouncy Castle 等软件 Provider,生成的私钥将不在 Keystore 保护之下。选择合适的 Provider 遵循以下原则:
- AndroidKeyStore:私钥强制存储在系统安全区域(TEE/StrongBox),私钥不可通过
getEncoded()导出。必须用于生产环境 RSA 密钥生成。 - 其他 Provider(BC、SC):私钥以明文或加密形式存在于进程内存或应用私有目录,可被反编译或 Hook 窃取。仅用于兼容性测试或纯软件加密场景。
- Provider 获取方式:通过
KeyStore.getInstance("AndroidKeyStore")获得实例,无需显式加载。
KeyPairGenerator.getInstance("RSA") 时忘记指定 Provider,或在 KeyStore.load() 之前就尝试生成密钥,会导致 KeyStoreException: KeyStore not initialized。必须按照 初始化 KeyStore → 初始化 KeyPairGenerator → 生成密钥对 的顺序操作。
2.4 代码示例:环境初始化与 Provider 验证
以下示例展示如何在 Android 6.0+ 设备上正确初始化 Keystore 并验证 Provider 是否生效:
// 1. 获取 AndroidKeyStore 实例
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null); // 初始化,null 参数表示加载空密钥库
// 2. 检查 Provider 是否硬件安全(可选)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Provider provider = keyStore.getProvider();
String providerName = provider.getName();
// 输出应为 "AndroidKeyStore"
android.util.Log.d("KeyStoreEnv", "Provider: " + providerName);
// 3. 验证是否支持 RSA(通常支持)
KeyPairGenerator kpg = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
);
android.util.Log.d("KeyStoreEnv", "RSA via AndroidKeyStore is available.");
}
上述代码必须在 API 23+ 上运行。若 minSdkVersion 低于 23,需用 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ... } 包裹。
2.5 环境准备架构总览
下图总结了密钥生成前所需的环境要素及相互关系:
2.6 常见错误与调试
- KeyStoreNotFoundException:API 等级低于 18,或模拟器不支持时出现。应在
try-catch中捕获并提示用户升级系统。 - ProviderNotFoundException:调用
KeyPairGenerator.getInstance("RSA", "AndroidKeyStore")时若 Provider 未注册,通常是因为 SDK 版本不足。检查Build.VERSION.SDK_INT。 - 硬件支持检测:可通过
keyStore.getProvider().getServices()枚举所有服务,但更简单的方式是尝试生成密钥,若失败再降级。
adb logcat 中过滤 KeyStore 或 KeyPairGenerator 日志,可看到 Provider 注册信息。例如:D/KeyStoreEnv: Provider: AndroidKeyStore 表示选择正确。