为数字凭据实现由硬件支持的证明

在使用 OpenID 可验证凭据颁发 (OpenID4VCI) 规范的典型数字凭据颁发流程中,颁发者需要知道待签名的凭据中的密钥存储在安全位置。android_keystore_attestation 证明类型(一种与 OpenID4VCI 搭配使用的格式)可提供来自 Android 密钥库的硬件签名报告,确保密钥锁定在可信执行环境 (TEE) 或 StrongBox 中,无法导出或克隆。

硬件证明概览

在 Android Keystore 中生成密钥时,系统可以生成认证证书。此证书由受设备硬件保护的密钥签名,该密钥可追溯到 Google 持有的信任根。

android_keystore_attestation 证明是 X.509 证书链的数组。每个链都代表一个身份验证密钥,其结构为叶证书后跟中间证书。

  • 叶证书:包含密钥和 Android 特定的认证扩展。
  • 中间证书:将叶证书连接到 Android 根证书。

验证步骤

签发者应针对证明执行多项验证。

  • 找到链中包含 Android 认证扩展(通常是叶证书)的证书。此证书包含 Android 密钥库生成的密钥的证明数据。
  • 验证扩展程序中的 attestationChallenge 字段是否与协议提供的 c_nonce 匹配,以防止重放攻击。
  • 验证您感兴趣的扩展程序中所有断言的值。
  • 针对 Android Keystore 证书执行撤消检查。

证明中的值来自多个来源:

  • 发布者:发布者会提供各种值,最常见的值会放入发布者元数据格式中,以便在展示时进行过滤。
  • 持有者:软件包名称和签名等值来自持有者。这些证件不会通过标准签发程序共享,需要由持证人自行获取。
  • 协议:包含 attestationChallenge 的随机数等值来自协议。

如需查看有关验证证明数据的更完整说明,请参阅以下资源:

证明格式

在凭据请求中,android_keystore_attestation 证明包含在以下示例中:

{
  "type": "array",
  "description": "An array of certificate chains. Each chain attests a single key.",
  "items": {
    "type": "array",
    "description": "An X.509 certificate chain. Each certificate is a Base64-encoded string. The first element in the chain is the leaf certificate with the extension, the last is the Android Keystore root certificate.",
    "items": {
      "type": "string",
      "description": "A single X.509 certificate (Base64-NoWrap padded DER encoded)."
    },
    "minItems": 1
  },
  "minItems": 1
}

然后,它会存储在凭据请求的 proofs 对象中。

{
  "credential_configuration_id": "org.iso.18013.5.1.mDL",
  "proofs": {
    "android_keystore_attestation": [
      [
        "MII...", // Leaf certificate (contains Keystore extension)
        "MII...", // Intermediate certificate
        "MII..."  // Android Root certificate
      ],
      [ "MII...", "MII...", "MII..." ] // second proof
    ]
  }
}

发卡机构元数据格式

签发方通过在给定凭据配置的 proof_types_supported 对象中包含 android_keystore_attestation 对象来指明其支持的证明类型。

以下是面向发行方的 android_keystore_attestation 对象示例:

{
  "type": "object",
  "properties": {
    "proof_signing_alg_values_supported": {
      "type": "array",
      "description": "REQUIRED. As defined in OpenID4VCI 1.0 Section 12.2.4.",
      "items": {
        "type": "string",
        "description": "Cryptographic algorithm identifiers used in the proof_signing_alg_values_supported Credential Issuer metadata parameter for this proof type are case sensitive strings and SHOULD be one of those defined in [IANA.JOSE]."
      },
      "minItems": 1
    },
    "key_attestations_required": {
      "type": "object",
      "description": "OPTIONAL. Specifies the minimum attestation requirements.",
      "properties": {
        "key_mint_security_level": {
          "type": "string",
          "description": "OPTIONAL. Minimum accepted keyMintSecurityLevel. Values defined in https://source.android.com/docs/security/features/keystore/attestation#securitylevel-values.",
          "enum": ["Software", "TrustedEnvironment", "StrongBox"],
          "default": "TrustedEnvironment"
        },
        "user_auth_types": {
          "type": "array",
          "description": "OPTIONAL. A list of authentication types which can authorize the use of the key. If empty, no authentication is required. If multiple, any are allowed.",
          "items": {
            "type": "string",
            "description": "Allowed values are 'LSKF' and 'BIOMETRIC'. These values are meant to mimic the values used during the key generation process here.",
            "enum": ["LSKF", "BIOMETRIC"]
          },
          "default": []
        }
      }
    }
  },
  "required": ["proof_signing_alg_values_supported"]
}

以下是外部 proof_types_supported 对象的示例:

{
  "credential_configurations_supported": {
    "org.iso.18013.5.1.mDL": {
      "format": "mso_mdoc",
      "doctype": "org.iso.18013.5.1.mDL",
      "cryptographic_binding_methods_supported": [
        "cose_key"
      ],
      "credential_signing_alg_values_supported": [
        -7, -9
      ],
      "proof_types_supported": {
        "android_keystore_attestation": {
          "proof_signing_alg_values_supported": [
            "ES256" // ecdsaWithSHA256
          ],
          "key_attestations_required" : {
            // OPTIONAL String - Representing the minimum accepted value for keyMintSecurityLevel values
            // defined here ("Software"|"TrustedEnvironment"|"StrongBox"). Default value: "TrustedEnvironment"
            "key_mint_security_level": "TrustedEnvironment",
            // OPTIONAL List of Strings - Representing all allowed values for userAuthType values defined here.
            // [] value will represent noAuthRequired. Default value: [].
            "user_auth_types": ["LSKF", "BIOMETRIC"]
          }
        }
      }
    }
  }
}

将 VCI 认证声明映射到 Android Keystore

此表提供了一个信息性映射,可帮助熟悉标准 OpenID4VCI 证明类型的实体了解 Android Keystore 证明中类似概念的位置。

VCI 证明声明

android_keystore_attestation 位置

预期价值位置

iss

密钥库根证书的公钥

不适用

iat

认证扩展程序中的 creationDateTime

不适用

exp

叶证书中的 validUntil 字段

不适用

attested_keys

每个链的叶证书中包含的公钥

不适用

key_storage

认证扩展程序中的 keyMintSecurityLevel

所选发卡机构:发卡机构元数据中的 key_mint_security_level 字段

user_authentication

证明扩展程序中的 userAuthTypenoAuthRequired

所选发卡机构:发卡机构元数据中的 user_auth_types 字段

nonce

认证扩展程序中的 attestationChallenge

来自协议:VCI 中描述的随机数端点c_nonce

认证

不适用

不适用

status

不适用

不适用