You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何判断AndroidKeyStore生成的密钥是否为硬件加密(TEE/SE)?

Nexus 6(Android7.1.1)密钥硬件存储判定问题解答

核心结论先给你吃定心丸

你的EC密钥**确实是存储在硬件加密环境(TEE)**里的!出现keyInfo.isInsideSecureHardware=falseKeyChain.isBoundKeyAlgorithm=true的情况,是Nexus 6这个特定设备+Android7.x版本的系统实现特性导致的,并非你的代码问题。

为什么两个API返回结果矛盾?

咱们得先搞清楚这两个API的底层逻辑差异:

  • KeyInfo.isInsideSecureHardware(API23+):官方文档说它用来判断密钥是否在安全硬件(SE/TEE)中,但在Nexus 6的Android7.x系统里,这个API的实现比较局限——它只把**Secure Element(SE)算作“安全硬件”,而Nexus 6的EC密钥实际是存在Trusted Execution Environment(TEE)**中的,所以会返回false
  • KeyChain.isBoundKeyAlgorithm(algorithm):这个旧API的设计是判断密钥是否绑定到设备硬件(不管是TEE还是SE),在Nexus 6的7.1.1系统中,它能正确识别TEE中的密钥,所以返回true

你的检查函数优化建议

你当前的函数逻辑已经做了很好的兼容,尤其是最后用keyInfo.isInsideSecureHardware || KeyChain.isBoundKeyAlgorithm(algorithm)的逻辑,刚好能覆盖Nexus 6这类系统实现有差异的设备。这里可以给你做一点小优化,让代码更健壮:

优化后的检查函数

fun checkKeyInHardware(): Boolean {
    val key = androidKeyStore.getKey(AUTH_ALIAS, null) as? PrivateKey ?: run {
        Log.d("checkKeyInHardware", "Failed to get private key")
        return false
    }
    val algorithm = key.algorithm
    Log.d("checkKeyInHardware", "Key algo = $algorithm")
    val isBoundToHardware = KeyChain.isBoundKeyAlgorithm(algorithm)
    Log.d("checkKeyInHardware", "KeyChain.isBoundKeyAlgorithm = $isBoundToHardware")

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val factory = KeyFactory.getInstance(algorithm, androidKeyStoreProvider)
        val keyInfo = try {
            factory.getKeySpec(key, KeyInfo::class.java)
        } catch (e: InvalidKeySpecException) {
            Log.d("checkKeyInHardware", "Key not stored in AndroidKeyStore")
            null
        } ?: run {
            Log.d("checkKeyInHardware", "KeyInfo is null")
            return false
        }
        val isInSecureHardware = keyInfo.isInsideSecureHardware
        Log.d("checkKeyInHardware", "keyInfo.isInsideSecureHardware = $isInSecureHardware")
        // 兼容Nexus 6这类TEE未被isInsideSecureHardware识别的设备
        isInSecureHardware || isBoundToHardware
    } else {
        isBoundToHardware
    }
}

关于你的密钥生成代码

你的生成逻辑完全没问题:

  • API25时不会触发StrongBox相关代码(StrongBox是API28才引入的特性),所以密钥会正常生成在Nexus 6的TEE中。
  • Nexus 6的TEE完全支持EC密钥的存储和加密操作,所以你的密钥安全性是有保障的。

内容的提问来源于stack exchange,提问作者kyo171

火山引擎 最新活动