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 环境准备架构总览

下图总结了密钥生成前所需的环境要素及相互关系:

密钥生成环境准备架构 最低 API 等级 API 23+ (Android 6.0+) 硬件安全 TEE / StrongBox 依赖声明 build.gradle (可选) security-crypto:1.1.0 Provider 选择 AndroidKeyStore 私钥不可导出 运行时初始化 KeyStore.getInstance("AndroidKeyStore").load(null) 验证:Provider 名称 == "AndroidKeyStore" minSdk < 23 运行时降级 硬件不可用 软件回退

2.6 常见错误与调试

  1. KeyStoreNotFoundException:API 等级低于 18,或模拟器不支持时出现。应在 try-catch 中捕获并提示用户升级系统。
  2. ProviderNotFoundException:调用 KeyPairGenerator.getInstance("RSA", "AndroidKeyStore") 时若 Provider 未注册,通常是因为 SDK 版本不足。检查 Build.VERSION.SDK_INT。
  3. 硬件支持检测:可通过 keyStore.getProvider().getServices() 枚举所有服务,但更简单的方式是尝试生成密钥,若失败再降级。
调试推荐:在 adb logcat 中过滤 KeyStore 或 KeyPairGenerator 日志,可看到 Provider 注册信息。例如:
D/KeyStoreEnv: Provider: AndroidKeyStore 表示选择正确。