如何检查Android手机是否支持TEE?

8

我已经阅读了这两篇文章:OneTwo,但仍有疑问。

我使用KeyStore(Android 9)生成AES密钥,并使用isInsideSecureHardware()方法检查密钥是否isInsideSecureHardware。返回值为False。代码示例可以在这里这里找到。

public boolean isInsideSecureHardware ()

如果密钥驻留在安全硬件内部(例如,可信执行环境(TEE)或安全元件(SE)),则返回true。此类密钥的密钥材料仅在安全硬件内以明文形式提供,并且不会在其外部公开。

因此,我想进一步确认我的手机设备(华为P20)是否支持TEE。

问题:

  1. 如果手机支持TEE,则由KeyStore生成的密钥将自动存储到TEE中吗?我需要在Java中进行任何手动配置吗?我听说只要使用KeyStore.getInstance()KeyGenerator.getInstance(算法,KeyStore名称),密钥就会自动存储在TEE中。但我不确定这是真的还是假的?

  2. 如果Q1的答案是“需要手动配置”,那么它就成为了isInsideSecureHardware()返回False的原因,对吗?如果Q1的答案是“自动”,则忽略Q2。

  3. 有没有直接在Java中检查手机是否支持TEE的方法?

2个回答

6

@JensV是正确的:如果您在keyGenParameterSpecBuilder上设置了setIsStrongBoxBacked,则如果不支持StrongBox,则密钥生成将失败并出现StrongBoxUnavailableException。然而,中间情况——即存在TEE(即在安全硬件内生成和使用密钥),但不支持StrongBox——更加棘手。

一般来说,最好的方法是实际在设备上生成密钥,然后在服务器上对其执行HW密钥认证——通过查看已签名的密钥属性来检查确切的硬件支持程度:

  • 在服务器端生成一个随机字节字符串,称为nonce,并将其传递到设备上
  • 在设备上生成一个密钥,通过在KeyGenParameterSpec构建器上调用setAttestationChallenge并传递从服务器获取的nonce(不要使用在设备上产生的nonce)来请求HW认证
  • 从Android Key Store请求密钥的认证链
  • 将认证数据(证书链)传递给您的服务器
  • 在服务器上验证认证(签名)链
  • 确认根证书与Google发布的根证书相匹配
  • 确认链中没有证书被吊销(针对CRL检查@https://android.googleapis.com/attestation/status
  • 检查叶子证书的Google Key Attestation扩展属性(OID 1.3.6.1.4.1.11129.2.1.17)
    • 确认nonce匹配(attestationChallenge
    • 查看KeyDescriptionattestationSecurityLevel
SecurityLevel ::= ENUMERATED {
    Software  (0),
    TrustedEnvironment  (1),
    StrongBox  (2),
}

TrustedEnvironmentStrongBox 都对应于硬件支持的密钥和加密操作。


1
我想补充一下,在对证明、安全密钥库密钥导入等主题进行了广泛的研究后,这是一个非常好的答案,它也解释了它们。它简洁地解释了需要做的一切,没有错过重要的细节(我在看你,Android文档)。如果可以的话,我会给100个赞。 - Gligor Atanasovski
请参考以下示例代码进行Android密钥认证客户端和服务器的开发 - https://github.com/davidbarkhuizen/android-key-attestation-client,https://github.com/davidbarkhuizen/android-key-attestation-server - david.barkhuizen

3
根据Android密钥库系统文档:
支持安装了Android 9(API级别28)或更高版本的设备上可使用StrongBox Keymaster,它是Keymaster HAL的实现,驻留在硬件安全模块中。该模块包含以下内容:
[...]
* 安全存储
[...]
检查StrongBox Keymaster中存储的密钥时,系统会与Trusted Execution Environment(TEE)验证密钥的完整性。
[...]
使用KeyStore类生成或导入密钥时,通过将true传递给setIsStrongBoxBacked()方法来指示首选将密钥存储在StrongBox Keymaster中。
据我理解,这意味着当您生成一个密钥并调用keyGenParameterSpecBuilder.setIsStrongBoxBacked(true)进行密钥配置时,您可以确保它由TEE支持。如果没有TEE可用,则会抛出StrongBoxUnavailableException。
因此,要检查是否有TEE可用,您可以尝试以这种方式生成密钥并查看是否有效。

1
StrongBox使用SE(独立硬件),而不是TEE(共享CPU,独立操作系统),它们并不完全相同? - TJCLARK
如果在 Android 9 以下(< API 28)呢? - TJCLARK
我添加了setIsStrongBoxBacked(true),但仍然不起作用。我在这里放置了代码:https://stackoverflow.com/questions/61230951/my-isinsidesecurityhardware-always-return-false - TJCLARK
不,你的假设是不正确的。即使TEE可用,keyGenParameterSpecBuilder.setIsStrongBoxBacked(true)也可能会抛出错误。您可以通过检查链来验证它。setIsStrongBoxBacked仅适用于StrongBox。 - Albert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接