利用密钥认证,对于将应用中使用的密钥存储在设备受硬件支持的密钥库中这一做法,您可以更加放心。以下部分介绍了如何验证硬件支持的密钥的属性,以及如何解释认证证书扩展数据的架构。
注意:在生产级环境中验证设备的硬件支持的密钥的属性前,您应确保设备支持硬件级密钥认证。为此,您需要确认认证证书链包含用 Google 认证根密钥签名的根证书,且密钥描述数据结构中的 attestationSecurityLevel
元素被设置为 TrustedEnvironment 安全等级。
此外,请务必验证证书链中的签名,并查看证书吊销状态列表,确认证书链中没有密钥被吊销。除非所有密钥均有效,而且根为上文提到的 Google 根密钥,否则您不能完全信任该认证。但是请注意,包含已吊销的证书的设备至少和仅支持软件认证的设备一样可信。在可信度方面,具有完全有效的认证是强有力的正面指标,但没有完全有效的认证则属于一般情况,并非是负面指标。
检索和验证硬件支持的密钥对
在密钥认证期间,您可以指定密钥对的别名。认证工具为此提供了一个证书链,您可以用它验证该密钥对的属性。
如果设备支持硬件级密钥认证,将使用认证根密钥为此证书链中的根证书签名,设备制造商已在出厂时将根密钥注入到设备的硬件支持的密钥库中。
注意:在附带硬件级密钥认证、搭载 Android 7.0(API 级别 24)或更高版本以及预装 Google Play 服务的设备上,根证书使用 Google 认证根密钥签名。您应验证此根证书是否是下面列出的证书。
如需实现密钥认证,请完成以下步骤:
- 使用
KeyStore
对象的getCertificateChain()
方法获取指向 X.509 证书链的引用,该证书链与硬件支持的密钥库关联。 -
使用
X509Certificate
对象的checkValidity()
方法检查每个证书的有效性。此外,还需验证根证书是否可信。注意:尽管您可以直接在应用中检查证书的吊销状态,但在您信任的独立服务器上完成此流程会更加安全。
-
在您信任的独立服务器上,获取指向最适合您工具集的 ASN.1 解析器库的引用。使用此解析器提取认证证书的扩展数据,此类数据显示在证书链的第一个元素中。
该密钥认证示例使用 Bouncy Castle 中的 ASN.1 解析器提取认证证书的扩展数据。在创建您自己的解析器时,您可以将此示例用作参考。
如需详细了解扩展数据的架构,请参阅证书扩展数据架构。
-
将从 ASN.1 解析器检索的扩展数据与您希望硬件支持的密钥将包含的值集合进行比较。
注意:尽管您可以在应用中直接完成此流程,但在您信任的独立服务器上检查证书的扩展数据更加安全。
根证书
认证的可信度取决于证书链的根证书。对于已通过预装 Google 一系列应用(包括 Google Play)所需测试的 Android 设备,以及搭载 Android 7.0(API 级别 24)或更高版本的设备,应使用 Google 硬件认证根证书签名的认证密钥。此证书如下所示:
-----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy ODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7 tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um AGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD VR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO BgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk Lmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD ggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB Pb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m qC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY DBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm QUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u JU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD CdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy ZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD qwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic MDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1 wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk -----END CERTIFICATE-----
如果您收到的认证链中的根证书是上述证书,而且认证链中的所有证书均未被吊销,您就可以知道:
- 您的密钥位于 Google 认为安全的硬件中;而且
- 它具有认证证书中说明的属性。
如果认证链具有任何其他根证书,Google 不会对硬件的安全性做出任何声明。这并不意味着您的密钥会受到攻击,只是认证不会证明密钥位于安全硬件中,您应该相应地调整安全假设。
如果根证书不是以上证书,可能有以下两个原因:
- 最可能的原因是,设备搭载的 Android 版本低于 7.0,而且不支持硬件认证。在这种情况下,Android 提供软件实现的认证,它可以生成相同类型的认证证书,但使用的是在 Android 源代码中硬编码的密钥进行签名。由于此签名密钥不是私密的,因此认证可能是假装提供安全硬件的攻击者创建的。
- 另一个可能的原因是设备不是 Google Play 设备。在这种情况下,设备制造商可以自由创建他们自己的根证书,并按照自己的意愿就认证的意义做出声明。有关具体情况,请参阅相应设备制造商的文档。请注意,在撰写本文时,Google 未发现有任何设备制造商采用这种做法。
证书吊销状态列表
认证密钥可能因多种原因被吊销,包括处理不当或怀疑被攻击者提取。因此,请务必根据官方证书吊销状态列表检查认证链中每个证书的状态。此列表由 Google 维护,并发布在以下网址:https://android.googleapis.com/attestation/status。该网址会返回一个 JSON 文件,其中包含任何不具有正常有效状态的证书的吊销状态。该 JSON 文件的格式遵循以下 JSON 架构(草稿 07)定义:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "entries": { "description" : "Each entry represents the status of an attestation key. The dictionary-key is the certificate serial number in lowercase hex.", "type": "object", "propertyNames": { "pattern": "^[a-f0-9]*$" }, "additionalProperties": { "type": "object", "properties": { "status": { "description": "[REQUIRED] Current status of the key.", "type": "string", "enum": ["REVOKED", "SUSPENDED"] }, "expires": { "description": "[OPTIONAL] UTC date when certificate expires in ISO8601 format (YYYY-MM-DD). Can be used to clear expired certificates from the status list.", "type": "string", "format": "date" }, "reason": { "description": "[OPTIONAL] Reason for the current status.", "type": "string", "enum": ["UNSPECIFIED", "KEY_COMPROMISE", "CA_COMPROMISE", "SUPERSEDED", "SOFTWARE_FLAW"] }, "comment": { "description": "[OPTIONAL] Free form comment about the key status.", "type": "string", "maxLength": 140 } }, "required": ["status"], "additionalProperties": false } } }, "required": ["entries"], "additionalProperties": false }
证书吊销状态列表示例:
{ "entries": { "2c8cdddfd5e03bfc": { "status": "REVOKED", "expires": "2020-11-13", "reason": "KEY_COMPROMISE", "comment": "Key stored on unsecure system" }, "c8966fcb2fbb0d7a": { "status": "SUSPENDED", "reason": "SOFTWARE_FLAW", "comment": "Bug in keystore causes this key malfunction b/555555" } } }
旧版 CRL
嵌入在旧版认证证书中的 CRL 网址将继续有效。新的认证证书不会再包含 CRL 网址扩展。旧版证书的状态也将包含在认证状态列表中,从而使开发者可以放心地使用该列表检查新版和旧版证书的状态。密钥认证示例中提供了有关如何正确验证 Android 认证密钥的示例。
证书扩展数据架构
密钥认证会对设备的硬件支持的密钥库中证书链的第一个证书中显示的扩展数据进行验证。此证书按照 ASN.1 架构存储信息。要查看与您使用的认证版本对应的架构,请在下面列出的架构中选择相应标签:
版本 3
KeyDescription ::= SEQUENCE { attestationVersion 3, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
版本 2
KeyDescription ::= SEQUENCE { attestationVersion 2, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
版本 1
KeyDescription ::= SEQUENCE { attestationVersion 1, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL, digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
以下列表对该架构中的每个元素进行了说明:
KeyDescription
值的这一顺序提供了有关通过密钥认证进行验证的密钥对的常规信息,并且可以轻松访问其他详情。
-
attestationVersion
- 密钥认证功能的版本。
-
attestationSecurityLevel
-
认证的安全等级。
警告:尽管可以认证存储在 Android 系统中的密钥(即,当
attestationSecurityLevel
的值设置为 Software 时),但如果 Android 系统受到攻击,您将不能信任这些认证。 -
keymasterVersion
- Keymaster 硬件抽象层 (HAL) 的版本。使用 0 表示版本 0.2 或 0.3,使用 1 表示版本 1.0,使用 2 表示版本 2.0。
-
keymasterSecurityLevel
- Keymaster 实现的安全等级。
-
uniqueId
- 此值用于标识设备,但只能在限定时间段内使用。此值通过计算得出,而且只能由系统应用使用。在所有其他应用中,
uniqueId
为空。 -
softwareEnforced
- 可选。由 Android 系统(而非设备的 TEE)强制执行的 Keymaster 授权列表。
-
teeEnforced
- 可选。由设备的 TEE 强制执行的 Keymaster 授权列表。
SecurityLevel
此数据结构表示软件功能(例如密钥对)受保护的程度基于其在设备中的位置。
因为该数据结构是一个枚举,所以它可以准确获取以下某个值:
- Software
- 用于创建和管理功能的逻辑在 Android 系统中实现。如果用于创建和存储密钥对,此位置没有 TEE 安全,但比应用的进程空间安全。
- TrustedEnvironment
- 用于创建和管理功能的逻辑在安全硬件(例如 TEE)中实现。如果用于创建和存储密钥对,此位置更安全,因为安全硬件更能抵御远程攻击。
- StrongBox
- 用于创建和管理功能的逻辑在专用硬件安全模块中实现。对于创建和存储密钥对,此位置更安全,因为它更能抵御远程攻击和针对模块的硬件攻击。
AuthorizationList
此数据结构包含密钥对的属性本身,如 Keymaster 硬件抽象层 (HAL) 中所定义。将这些值与设备的当前状态或一组预期值进行比较,以验证密钥对是否仍适用于您的应用。
每个字段名称对应一个名称相似的 Keymaster 授权标记。例如,授权列表中的 keySize
字段与 Tag::KEY_SIZE
Keymaster 授权标记对应。
以下列表中的每个字段都是可选字段:
-
purpose
- 与
Tag::PURPOSE
Keymaster 授权标记对应,其使用的标记 ID 值为 1。 -
algorithm
-
与
Tag::ALGORITHM
Keymaster 授权标记对应,其使用的标记 ID 值为 2。在认证
AuthorizationList
对象中,算法值始终为RSA
或EC
。 -
keySize
- 与
Tag::KEY_SIZE
Keymaster 授权标记对应,其使用的标记 ID 值为 3。 -
digest
- 与
Tag::DIGEST
Keymaster 授权标记对应,其使用的标记 ID 值为 5。 -
padding
- 与
Tag::PADDING
Keymaster 授权标记对应,其使用的标记 ID 值为 6。 -
ecCurve
-
与
Tag::EC_CURVE
Keymaster 授权标记对应,其使用的标记 ID 值为 10。Android 系统密钥库中用于生成椭圆曲线 (EC) 密钥对的参数集,该参数集使用 ECDSA 进行签名和验证。
-
rsaPublicExponent
- 与
Tag::RSA_PUBLIC_EXPONENT
Keymaster 授权标记对应,其使用的标记 ID 值为 200。 -
rollbackResistance
-
仅存在于密钥认证版本 3 中。
与
Tag::ROLLBACK_RESISTANT
Keymaster 授权标记对应,其使用的标记 ID 值为 303。 -
activeDateTime
- 与
Tag::ACTIVE_DATETIME
Keymaster 授权标记对应,其使用的标记 ID 值为 400。 -
originationExpireDateTime
- 与
Tag::ORIGINATION_EXPIRE_DATETIME
Keymaster 授权标记对应,其使用的标记 ID 值为 401。 -
usageExpireDateTime
- 与
Tag::USAGE_EXPIRE_DATETIME
Keymaster 授权标记对应,其使用的标记 ID 值为 402。 -
noAuthRequired
-
与
Tag::NO_AUTH_REQUIRED
Keymaster 授权标记对应,其使用的标记 ID 值为 503。 -
userAuthType
- 与
Tag::USER_AUTH_TYPE
Keymaster 授权标记对应,其使用的标记 ID 值为 504。 -
authTimeout
- 与
Tag::AUTH_TIMEOUT
Keymaster 授权标记对应,其使用的标记 ID 值为 505。 -
allowWhileOnBody
-
与
Tag::ALLOW_WHILE_ON_BODY
Keymaster 授权标记对应,其使用的标记 ID 值为 506。如果用户身上仍佩戴着设备,允许在密钥身份验证超时后使用密钥。请注意,安全的体感传感器可以确定设备是否正佩戴在用户身上。
-
trustedUserPresenceRequired
-
仅存在于密钥认证版本 3 中。
与
Tag::TRUSTED_USER_PRESENCE_REQUIRED
Keymaster 授权标记对应,其使用的标记 ID 值为 507。规定仅在用户提供了物理存在证明时,此密钥才可用。示例如下:
- 对于 StrongBox 密钥,以硬连接的方式将硬件按钮连接到 StrongBox 设备上的 PIN 码。
- 对于 TEE 密钥,只要 TEE 拥有对扫描器的独占控制权并执行指纹匹配过程,指纹身份验证就会提供存在证明。
-
trustedConfirmationRequired
-
仅存在于密钥认证版本 3 中。
与
Tag::TRUSTED_CONFIRMATION_REQUIRED
Keymaster 授权标记对应,其使用的标记 ID 值为 508。规定仅在用户确认使用审批令牌为数据签名时,此密钥才可用。如需详细了解如何获取用户确认,请参阅 Android 受保护的确认。
注意:此标记仅适用于目的为
SIGN
的密钥。 -
unlockedDeviceRequired
-
仅存在于密钥认证版本 3 中。
与
Tag::UNLOCKED_DEVICE_REQUIRED
Keymaster 授权标记对应,其使用的标记 ID 值为 509。 -
allApplications
-
与
Tag::ALL_APPLICATIONS
Keymaster 授权标记对应,其使用的标记 ID 值为 600。指示设备上的所有应用是否都可以访问密钥对。
-
applicationId
- 与
Tag::APPLICATION_ID
Keymaster 授权标记对应,其使用的标记 ID 值为 601。 -
creationDateTime
- 与
Tag::CREATION_DATETIME
Keymaster 授权标记对应,其使用的标记 ID 值为 701。 -
origin
-
与
Tag::ORIGIN
Keymaster 授权标记对应,其使用的标记 ID 值为 702。 -
rollbackResistant
-
仅存在于密钥认证版本 1 和 2 中。
与
Tag::ROLLBACK_RESISTANT
Keymaster 授权标记对应,其使用的标记 ID 值为 703。 -
rootOfTrust
-
与
Tag::ROOT_OF_TRUST
Keymaster 授权标记对应,其使用的标记 ID 值为 704。如需了解更多详情,请参阅介绍 RootOfTrust 数据结构的部分。
-
osVersion
-
与
Tag::OS_VERSION
Keymaster 授权标记对应,其使用的标记 ID 值为 705。与 Keymaster 关联的 Android 操作系统的版本,使用一个 6 位整数表示。例如,版本 8.1.0 表示为 080100。
只有 Keymaster 版本 1.0 或更高版本在授权列表中包含此值。
-
osPatchLevel
-
与
Tag::PATCHLEVEL
Keymaster 授权标记对应,其使用的标记 ID 值为 706。与 Keymaster 中使用的安全补丁程序关联的月份和年度,使用一个 6 位整数表示。例如,2018 年 8 月的补丁程序表示为 201808。
只有 Keymaster 版本 1.0 或更高版本在授权列表中包含此值。
-
attestationApplicationId
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_APPLICATION_ID
Keymaster 授权标记对应,其使用的标记 ID 值为 709。如需了解更多详情,请参阅介绍 AttestationApplicationId 数据结构的部分。
-
attestationIdBrand
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_BRAND
Keymaster 标记对应,其使用的标记 ID 值为 710。 -
attestationIdDevice
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_DEVICE
Keymaster 标记对应,其使用的标记 ID 值为 711。 -
attestationIdProduct
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_PRODUCT
Keymaster 标记对应,其使用的标记 ID 值为 712。 -
attestationIdSerial
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_SERIAL
Keymaster 标记对应,其使用的标记 ID 值为 713。 -
attestationIdImei
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_IMEI
Keymaster 授权标记对应,其使用的标记 ID 值为 714。 -
attestationIdMeid
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_MEID
Keymaster 授权标记对应,其使用的标记 ID 值为 715。 -
attestationIdManufacturer
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_MANUFACTURER
Keymaster 授权标记对应,其使用的标记 ID 值为 716。 -
attestationIdModel
-
仅存在于密钥认证版本 2 和 3 中。
与
Tag::ATTESTATION_ID_MODEL
Keymaster 标记对应,其使用的标记 ID 值为 717。 -
vendorPatchLevel
-
仅存在于密钥认证版本 3 中。
与
Tag::VENDOR_PATCHLEVEL
Keymaster 授权标记对应,其使用的标记 ID 值为 718。规定为了使用此密钥而必须在设备上安装的供应商映像安全补丁程序级别。此值以 YYYYMMDD 的形式显示,表示供应商安全补丁程序的日期。例如,如果密钥在 Android 设备上生成,且相应设备安装了供应商于 2018 年 8 月 1 日提供的安全补丁程序,其值将表示为 20180801。
-
bootPatchLevel
-
仅存在于密钥认证版本 3 中。
与
Tag::BOOT_PATCHLEVEL
Keymaster 授权标记对应,其使用的标记 ID 值为 719。规定为了使用此密钥而必须在设备上安装的内核映像安全补丁程序级别。此值以 YYYYMMDD 的形式显示,表示系统安全补丁程序的日期。例如,如果密钥在 Android 设备上生成,且相应设备安装了系统于 2018 年 8 月 5 日提供的安全补丁程序,其值将表示为 20180805。
RootOfTrust
这个值集合可以定义与设备状态有关的密钥信息。
以下列表中的每个字段都是必选字段:
-
verifiedBootKey
-
验证系统映像的密钥的安全哈希值。建议您针对此哈希值使用 SHA-256 算法。
-
deviceLocked
- 在设备的引导加载程序处于锁定状态时为 true,这将启用启动时验证检查,并防止将未签名的设备映像刷写到设备上。如需详细了解此功能,请参阅启动时验证文档。
-
verifiedBootState
- 设备的启动状态(按照启动时验证功能)。
-
verifiedBootHash
-
仅存在于密钥认证版本 3 中。
受启动时验证保护的所有数据的摘要。对于使用 Android 启动时验证实现(针对启动时验证)的设备,此值包含 VBMeta 结构或启动时验证元数据结构的摘要。
如需详细了解如何计算此值,请参阅 VBMeta 摘要。
VerifiedBootState
此数据结构提供设备的当前启动状态,表示在设备完成启动后为用户和应用提供的保护级别。如需详细了解此功能,请参阅“启动时验证”文档中的启动状态部分。
此数据结构是一个枚举,它可以准确获取以下某个值:
- Verified
-
用于指明完整的信任链,其中包含引导加载程序、启动分区和所有已验证的分区。
当设备处于此启动状态时,
verifiedBootKey
是嵌入式设备证书的哈希值,设备制造商已在出厂时将其添加到设备的 ROM 中。 - SelfSigned
-
用于指明嵌入式设备证书已验证设备的启动分区及签名有效。
当设备处于此启动状态时,
verifiedBootKey
是用户安装的证书的哈希值,它将为一个启动分区签名,用户可以将其添加到设备中代替制造商提供的原始启动分区。 - Unverified
- 用于指明用户可以随意修改设备。因此,用户应负责验证设备的完整性。
- Failed
- 用于指明设备验证失败。认证证书决不能将此值用作
VerifiedBootState
。
AttestationApplicationId
此数据结构反映了 Android 平台允许哪些应用使用认证中的密钥材料。当且仅当多个软件包共享同一 UID 时,此 ID 才可以包含多个软件包。这一八位字节的字符串本身按照以下 ASN.1 架构设置格式:
AttestationApplicationId ::= SEQUENCE { package_infos SET OF AttestationPackageInfo, signature_digests SET OF OCTET_STRING, } AttestationPackageInfo ::= SEQUENCE { package_name OCTET_STRING, version INTEGER, }
- package_infos
- 一组
AttestationPackageInfo
对象,每个对象都提供软件包名称和版本号。 - signature_digests
-
应用的签名 blob 的 SHA-256 摘要集,包含在调用
getPackageInfo()
时所返回的PackageInfo
的signatures
字段中。以下代码段展示了一个摘要集的示例:{SHA256(PackageInfo.signature[0]), SHA256(PackageInfo.signature[1]), ...}