KeyStore (Android)——核心概念、API与加密存储的工作原理

作者: IT Sectr 发布日期: 2026-03-14 阅读时间: 10 分钟

KeyStore (Android) ——是 Java Cryptography Architecture (JCA) 加密提供者在 Android 中的实现,用于安全存储密钥并支持硬件隔离能力。从 Android 4.3 (API 18) 开始,KeyStore 通过 Keymaster HAL 支持硬件密钥,从 Android 9 (API 28) 开始支持用于专用 Secure Element 中密钥的 StrongBox Keymaster。根据 Android Security Documentation,“AndroidKeyStore” 提供者取代了标准的 Bouncy Castle 或 OpenSSL KeyStore,为密钥提供系统级保护,防止未经授权的提取。

主要要点

  • Android KeyStore ——用于存储密钥的 JCA 提供者,支持 TEE、StrongBox 和生物识别保护
  • KeyGenParameterSpec 在创建密钥时指定算法、用途、摘要、填充和生物识别
  • Keymaster HAL 在 Software、TEE 和 StrongBox 层级别上实现硬件加密操作
  • Key Attestation (API 28+) 允许服务器验证密钥是在 Android KeyStore 硬件环境中创建的
  • 密钥别名——应用程序用以在 Keystore 中访问密钥的字符串;一个别名对应一个密钥

Android 中的 KeyStore 是什么?

Android 中的 KeyStore ——不是独立的应用程序或文件,而是实现 java.security.KeyStore 接口的加密提供者。它提供统一的 API来存储和使用私钥、对称密钥以及受信任的证书颁发机构 (CA) 的证书。该提供者以 “AndroidKeyStore” 名义注册,可通过标准的 KeyStore.getInstance() 访问。

Android KeyStore 的演变

在 Android 4.3 之前,加密操作通过 Bouncy Castle 以软件方式执行。Android 4.3 引入了 Keymaster HAL 1.0,允许在 ARM TrustZone 上使用 TEE。Android 6.0 (API 23) 添加了 Keymaster 2.0,支持通过指纹进行硬件认证。Android 9 (API 28) 引入了 Keymaster 4.0 和用于专用 Secure Element 的 StrongBox Keymaster。

Keymaster 的每个版本都增加了新功能,并提高了密钥隔离能力。现代设备 (2022+) 必须支持 Keymaster 4.0 才能获得 Google Mobile Services 认证,这保证了所有 Android 应用程序都能使用 TEE。

架构和组件

Android KeyStore 由三个组成:Java API (KeyStore, KeyPairGenerator)、系统进程 keystore (C++,作为 system service 工作) 和 Keymaster HAL (TEE 或 Secure Element 中的库)。应用程序调用 API,keystore 服务将请求路由到 Keymaster,操作在受保护环境中执行。

所有私钥存储在 TEE 中,无法从用户空间读取。连系统 keystore 服务都无法访问原始密钥——仅能访问指向 Keymaster 内部密钥的句柄。

KeyStore 作为加密提供者如何工作?

Android KeyStore 实现了 JCA 服务提供者的标准接口。当应用程序调用 Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”) 时,Android Security Provider 通过链条将操作委托给 Keymaster:Java → JNI → keystore service → Keymaster HAL。

提供者的注册

AndroidKeyStore 提供者在进程启动时自动注册。其优先级高于 Bouncy Castle 或 Conscrypt。因此,在调用 KeyStore.getInstance() 而不指定提供者时,多数情况下返回的是 AndroidKeyStore。明确调用时请使用 KeyStore.getInstance(“AndroidKeyStore”)。

每个 Android 应用程序在 KeyStore 中都有一个隔离的容器。具有相同 UID (shared userId) 的应用程序可以共享访问特定密钥,但标准配置保证应用程序 A 无法读取应用程序 B 的密钥。

KeyStore 的方法及其特点

load(null) ——初始化 KeyStore。对于 AndroidKeyStore,参数始终为 null。setEntry ——保存密钥并指定 KeyProtection (purposes、digest、padding)。getEntry ——获取 KeyStore.PrivateKeyEntry、SecretKeyEntry 或 TrustedCertificateEntry。containsAlias ——检查密钥是否存在。deleteEntry ——删除密钥(不可撤销)。

kotlin
import java.security.KeyStore
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties

object KeyStoreManager {
    private val keyStore by lazy {
        KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
    }

    fun createRsaKey(alias: String) {
        val spec = KeyGenParameterSpec.Builder(alias,
            KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
        ).setKeySize(2048)
         .setDigests(KeyProperties.DIGEST_SHA256)
         .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
         .build()

        val kpg = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA,
            "AndroidKeyStore"
        )
        kpg.initialize(spec)
        kpg.generateKeyPair()
    }
}

支持的算法和密钥类型

Android KeyStore 支持广泛的加密算法集合,具体取决于设备上的 Keymaster HAL 版本。开发者可以在尝试生成时通过 KeyGenParameterSpec.Builder 获取支持的算法列表——不兼容的参数会引起 InvalidAlgorithmParameterException。

非对称算法

RSA (1024–4096 位) ——用于签名 (PKCS1、PSS 使用 SHA-1/SHA-256/SHA-384/SHA-512) 和加密 (OAEP 使用 SHA-1/SHA-256)。EC (P-224、P-256、P-384、P-521) ——用于 ECDSA 签名和 ECDH 密钥协议。X25519Ed25519 ——从 Android 12 (API 31) 开始用于现代加密协议。

对于非对称密钥,始终在 Keymaster 内部生成,绝不导入私钥。导入的私钥不受硬件保护——它们存储在软件层中,在 AP 被攻击时容易受到损害。

对称算法

AES (128, 256 位) ——用于 CBC、CTR、GCM 模式下的对称加密。HMAC (SHA-1、SHA-256、SHA-512) ——用于消息认证。ChaCha20 (Android 12+) ——用于高性能流加密,配合 Poly1305 认证。

算法Keymaster用途API
RSAKM 1.0+签名、加密18+
ECKM 1.0+ECDSA、ECDH18+
AESKM 2.0+对称加密23+
HMACKM 2.0+认证码23+
ChaCha20KM 3.0+流加密31+
X25519/E25519KM 3.0+密钥交换31+

密钥类型及其序列化

KeyStore.PrivateKeyEntry ——包含私钥(不可导出)和证书链。KeyStore.SecretKeyEntry ——用于对称密钥。KeyStore.TrustedCertificateEntry ——用于受信任的 CA 证书。公钥可通过 keyStore.getCertificate(alias).publicKey 导出。

密钥生成和使用示例

让我们看一个完整的场景:生成 AES 密钥用于数据加密,以及生成 EC 密钥用于签名并配合生物识别保护。两个密钥都在 Android KeyStore 内部创建,支持硬件加速。

生成 AES 密钥用于加密

AES 密钥通过 KeyGenerator 配合 KeyGenParameterSpec 创建。参数:PURPOSE_ENCRYPT + PURPOSE_DECRYPT、BLOCK_MODE_GCM (推荐的带认证模式)、ENCRYPTION_PADDING_NONE (GCM 无需填充)。

kotlin
import javax.crypto.KeyGenerator
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec

fun generateAndEncrypt(alias: String, plainText: ByteArray): ByteArray {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setKeySize(256)
     .build()

    val kg = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    kg.initialize(spec)
    kg.generateKey()

    val cipher = Cipher.getInstance("AES/GCM/NoPadding")
    cipher.init(Cipher.ENCRYPT_MODE, getKeyFromStore(alias))
    return cipher.doFinal(plainText)
}

带生物识别保护的签名

EC 密钥设置 userAuthenticationRequired=true 后,每次签名操作前都需要用户认证。此时使用 BiometricPrompt 配合 CryptoObject,其中包含 Signature 对象。生物识别成功后,Keymaster 允许操作。

kotlin
fun createBiometricSignKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN
    ).setAlgorithmParameterSpec(
        ECGenParameterSpec("secp256r1")
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setUserAuthenticationRequired(true)
     .setInvalidatedByBiometricEnrollment(true)
     .build()

    val kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC,
        "AndroidKeyStore"
    )
    kpg.initialize(spec)
    kpg.generateKeyPair()
}

KeyStore 与设备安全

Android KeyStore 提供了硬件安全保证,软件密钥库 (JKS、BKS) 无法提供。密钥在 SoC 层面受到保护,即使完全控制 Android 用户空间也无法提取私钥。

Key Attestation (Android 8.1+)

Key Attestation——是一种机制,允许应用程序(以及服务器)验证密钥是在什么环境中创建的。Android Keystore 签署一个证书,包含密钥特性列表:算法、大小、purges、hardware-backed (True/False)、origin (GENERATED、IMPORTED)。服务器验证证书链一直到 Google 根证书。

这对于金融应用程序至关重要:服务器可以要求密钥在硬件环境中创建 (Hardware-Backed = True),并拒绝在软件 KeyStore 中创建的密钥。Key Attestation 可以防止攻击者将 Keystore 替换为仿真器的攻击。

生物识别信息变更时密钥的失效

setInvalidatedByBiometricEnrollment(true)意味着当用户的生物识别模板被修改或删除时,Keymaster 将自动删除密钥。这是对攻击者将自己的指纹添加到现有账户的攻击的保护。添加新指纹后,旧密钥将变得不可访问。

失败的生物识别认证尝试次数也由 Keymaster 管理。达到 maxBiometricAttempt (由制造商设置,通常为 5) 后,Keymaster 将所有使用生物识别密钥的操作暂停 30 秒。在 10 次失败尝试后,需要输入设备密码(秘密 PIN)才能解锁。

常见问题

Android KeyStore 和 Bouncy Castle KeyStore 有什么区别?

Bouncy Castle (BKS) ——是一种软件 KeyStore,将密钥存储在口令保护的文件中。Android KeyStore 使用硬件隔离 TEE/StrongBox。BKS 密钥可通过 root 访问提取,而 Android KeyStore 密钥则不能。BKS 适合用于 CA 证书,Android KeyStore 适合用于私钥。

同一个密钥可以既用于加密又用于签名吗?

可以,如果在生成时指定了 PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or PURPOSE_VERIFY。但最佳实践是为不同操作创建单独的密钥。这能限制一个密钥被泄露时的损失,并符合最小权限原则。

如何判断 Android KeyStore 中的密钥是否为硬件密钥?

使用KeyStore.getKeyCharacteristics(alias),可通过 android.security.keystore 访问。该方法返回一组标志:FLAG_HARDWARE ——密钥在 TEE 中,FLAG_SECURE_ELEMENT ——密钥在 StrongBox 中。如果没有标志,则密钥是软件密钥。

删除所有生物识别模板会发生什么?

所有使用 setInvalidatedByBiometricEnrollment(true) 创建的密钥都将被 Keymaster 自动失效。尝试使用时,应用程序将收到 KeyPermanentlyInvalidatedException。使用这些密钥加密的数据将永久丢失。

Android KeyStore 支持密钥备份吗?

硬件密钥(在 TEE/StrongBox 中)不支持备份——它们与特定设备绑定。软件密钥可以包含在 Google Drive 备份中。要在设备之间转移数据,请在服务器上加密数据,然后在新设备上解密。

总结

  • Android KeyStore ——通过 Keymaster HAL 在 TEE/StrongBox 中实现硬件隔离密钥存储的 JCA 提供者
  • KeyGenParameterSpec 配置密钥的算法、大小、purges、摘要、生物识别和时间限制
  • RSA (KM 1.0+)、EC (KM 1.0+)、AES (KM 2.0+)、ChaCha20 (KM 3.0+) ——支持的算法,各自具有不同的 Keymaster 级别
  • Key Attestation (API 28+) 允许服务器端验证密钥的硬件来源
  • 生物识别密钥保护通过 setUserAuthenticationRequired + BiometricPrompt 配合 CryptoObject
  • 失效机制在生物识别信息变更时防止新增指纹的未经授权使用
  • 在 Android 应用程序中,使用 Android KeyStore 生成和存储具有硬件保护的加密密钥

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读