身份凭据
Android 设备使用身份凭据 库安全地管理设备上的凭据。身份凭据 库提供了许多由颁发者使用的安全功能。 以确保其与 Google 的集成尽可能安全。
已签名的 Nonce
身份凭据库接受了“质询”(在此 API 中称为 Nonce)(在检索设备身份证书时发送),发送到颁发者 在 RegisterDeviceRequest 中注册设备。 此 Nonce 已经过签名并嵌入到设备的认证扩展中 身份证书。这样,发行方就可以确信新近度 证明证书和认证没有被服务器重放 在通信过程中取得的成效
访问权限控制配置文件
访问控制配置文件是颁发者准确指定 希望存储在身份凭据中的数据受到保护。通过 颁发者能够指定是否需要用户身份验证才能访问数据 元素,以及用户必须执行身份验证的时长。未来(非 此功能的使用场景包括限制 访问该数据元素。关于如何设置访问权限控制格式的详细信息 可以采用 Credential 对象格式找到配置文件。
配置证明
配置证明对象是发行商知道 凭据已成功存储在身份凭据中。发卡机构应该 在 MSO 收到并验证证明之前, 预配。身份凭据文档中详细介绍了此对象。
对象格式
这些对象中的每一个都会在设备和 发卡机构。因此,Google 的服务器无法 这些对象,其中一些对象的格式可能与 其他 API 对象例如,凭据采用 CBOR 格式, ,因为这是 Android 级别的预期。
凭据
该凭据包含数据元素及其访问方式。它
包含两个主要对象:provisionedData 和 accessControlProfiles。通过
provisionedData 包含与指定的任何命名空间相关的
凭据类型。例如,对于移动驾照,此值应为
org.iso.18013.5.1和org.aamva.18013.5.1。数据条目和值
指定相关的访问控制配置文件。这是
以 ID 列表的形式执行,其中该 ID 对应一个访问控制配置文件,
accessControlProfiles 列表。在下面的示例中,每项数据中的 [0]
条目是指 ID 为 0(而不是索引 0)的访问控制配置文件。
下面是一个未经编码的 CBOR 地图数据项示例。
{ "provisionedData": { "org.iso.18013.5.1": [ { "name": "family_name", "value": "Smith", "accessControlProfiles": [ 1 ] }, { "name": "given_name", "value": "Stewart", "accessControlProfiles": [ 1 ] }, { "name": "birth_date", "value": { "tag": 1004, "value": "1965-09-01" }, "accessControlProfiles": [ 1 ] }, { "name": "issue_date", "value": { "tag": 1004, "value": "2022-08-01" }, "accessControlProfiles": [ 1 ] }, { "name": "expiry_date", "value": { "tag": 1004, "value": "2027-08-01" }, "accessControlProfiles": [ 1 ] }, { "name": "issuing_authority", "value": "IA", "accessControlProfiles": [ 1 ] }, { "name": "issuing_country", "value": "US", "accessControlProfiles": [ 1 ] }, { "name": "document_number", "value": "D04320785", "accessControlProfiles": [ 1 ] }, { "name": "portrait", "value": { "type": "Buffer", "data": [ 167, 30, 148, 218, 204, 75, 112, 162, 138, 40, 52, 63, 255 ] }, "accessControlProfiles": [ 1 ] }, { "name": "un_distinguishing_sign", "value": "USA", "accessControlProfiles": [ 1 ] }, { "name": "driving_privileges", "value": [ { "expiry_date": { "tag": 1004, "value": "2027-08-01" }, "issue_date": { "tag": 1004, "value": "2022-08-01" }, "vehicle_category_code": "B" } ], "accessControlProfiles": [ 1 ] }, { "name": "sex", "value": 1, "accessControlProfiles": [ 1 ] }, { "name": "height", "value": 170, "accessControlProfiles": [ 1 ] }, { "name": "weight", "value": 79, "accessControlProfiles": [ 1 ] }, { "name": "eye_colour", "value": "Blue", "accessControlProfiles": [ 1 ] }, { "name": "hair_colour", "value": "Gray", "accessControlProfiles": [ 1 ] }, { "name": "age_in_years", "value": 57, "accessControlProfiles": [ 1 ] }, { "name": "age_over_18", "value": true, "accessControlProfiles": [ 1 ] }, { "name": "age_over_21", "value": true, "accessControlProfiles": [ 1 ] }, { "name": "resident_address", "value": "1600 Amphitheatre Pkwy ", "accessControlProfiles": [ 1 ] }, { "name": "issuing_jurisdiction", "value": "US-CA", "accessControlProfiles": [ 1 ] }, { "name": "resident_city", "value": "Mountain View", "accessControlProfiles": [ 1 ] }, { "name": "resident_state", "value": "CA", "accessControlProfiles": [ 1 ] }, { "name": "resident_postal_code", "value": "94043", "accessControlProfiles": [ 1 ] }, { "name": "resident_country", "value": "US", "accessControlProfiles": [ 1 ] } ], "org.iso.18013.5.1.aamva": [ { "name": "DHS_compliance", "value": "F", "accessControlProfiles": [ 1 ] }, { "name": "domestic_driving_privileges", "value": [ { "domestic_vehicle_class": { "domestic_vehicle_class_code": "D", "domestic_vehicle_class_description": "Operator", "expiry_date": { "tag": 1004, "value": "2027-08-01" }, "issue_date": { "tag": 1004, "value": "2022-08-01" } }, "domestic_vehicle_restrictions": [ { "domestic_vehicle_restriction_code": "B", "domestic_vehicle_restriction_description": "Corrective lenses (also automated - vision screening)" } ] } ], "accessControlProfiles": [ 1 ] }, { "name": "aamva_version", "value": "1", "accessControlProfiles": [ 1 ] }, { "name": "family_name_truncation", "value": "N", "accessControlProfiles": [ 1 ] }, { "name": "given_name_truncation", "value": "N", "accessControlProfiles": [ 1 ] }, { "name": "organ_donor", "value": true, "accessControlProfiles": [ 1 ] } ] }, "accessControlProfiles": [ { "id": 1, "userAuthenticationRequired": true, "timeoutMillis": 10000 } ] }
然后,此对象应以 CBOR 格式编码、加密,然后 base64 编码。如果在测试环境中,并且数据未加密, 应以 CBOR 格式编码,然后再使用 base64 编码。
请注意,上面的示例是未编码的 CBOR 映射,而不是 JSON。如果 JSON 字符串 编码到 CBOR 中,Android 设备将无法正确解析。
移动设备安全对象
ISO/IEC 18013-5 定义了移动安全对象 (MSO),以确保 mDL 数据未被篡改,并且由受信任的机构发布。
MSO 包含以下内容:
- 摘要值:这些是为每项数据生成的唯一值 元素。它们用于验证数据是否 自 MSO 签署以来发生了更改。
- 设备密钥:这是为每个移动设备生成的唯一密钥 存储凭据。用于将 MSO 绑定到设备,以及 以防止在其他设备上使用。
- 有效性信息:包括 MSO 有效。
- IA 签名:这是由系统创建的数字签名 由发证机关 (IA) 使用其私钥提供。 用于验证 MSO 是否由受信任的机构发布。
MSO 具有以下 CCDL 结构:
MobileSecurityObjectBytes = #6.24(bstr .cbor MobileSecurityObject)
MobileSecurityObject = {
"digestAlgorithm" : tstr, ; Message digest algorithm used
"valueDigests" : ValueDigests, ; Array of digests of all data elements
"deviceKeyInfo" : DeviceKeyInfo,
"docType" : tstr, ; DocType as used in Documents
"validityInfo" : ValidityInfo
}
DeviceKeyInfo = {
"deviceKey" : DeviceKey
? "keyAuthorizations" : KeyAuthorizations,
? "keyInfo" : KeyInfo
}
DeviceKey = COSE_Key ; Device key in COSE_Key as defined in RFC 8152
KeyAuthorizations = {
? "nameSpaces" : AuthorizedNameSpaces
? "dataElements" : AuthorizedDataElements
}
AuthorizedNameSpaces = [+ NameSpace]
AuthorizedDataElements = {+ NameSpace => DataElementsArray}
DataElementsArray = [+ DataElementIdentifier]
KeyInfo = { * int => any} ; Positive integers are RFU, negative integers may be used for proprietary use
ValueDigests = {
"nameSpaces" : NameSpacesDigests
}
NameSpacesDigests = {
+ NameSpace => DigestIDs
}
DigestIDs = {
+ DigestID => Digest
}
ValidityInfo = {
"signed" : tdate,
"validFrom" : tdate,
"validUntil" : tdate,
? "expectedUpdate" : tdate
}
NameSpace = tstr ; NameSpace as used in IssuerSigned
DigestID = uint ; DigestID as used in IssuerSig静态身份验证数据
静态身份验证数据,其中包括
digestIdMapping 和 issuerAuth 应由发卡机构构造。
特定命名空间的 digestIdMapping 由
IssuerSignedItem 实例,每个实例的 elementValue 属性均为 null 值。
此外,issuerAuth 是通过对
MobileSecurityObjectBytes(使用 COSE_Sign1)。
StaticAuthDataBytes = (bstr .cbor StaticAuthData) StaticAuthData = { "digestIdMapping" : DigestIdMapping, "issuerAuth" : IssuerAuth } DigestIdMapping = { NameSpace => [ + IssuerSignedItemBytes ] } ; Defined in ISO 18013-5 ; NameSpace = String DataElementIdentifier = String DigestID = uint IssuerAuth = COSE_Sign1 ; The payload is MobileSecurityObjectBytes IssuerSignedItemBytes = #6.24(bstr .cbor IssuerSignedItem) IssuerSignedItem = { "digestID" : uint, ; Digest ID for issuer data auth "random" : bstr, ; Random value for issuer data auth "elementIdentifier" : DataElementIdentifier, ; Data element identifier "elementValue" : DataElementValue ; Data element value }
调用 /provisionMobileSecurityObjects 后
端点,则 StaticAuthDataBytes 会使用 HPKE 进行加密,然后传输
作为响应的一部分。
这里有 代码示例 用于构建 MSO 和静态身份验证数据。