デジタル認証情報にハードウェア格納型の証明書を実装する

OpenID for Verifiable Credential Issuance(OpenID4VCI)仕様を使用した一般的なデジタル認証情報発行フローでは、発行者は、署名される認証情報内の鍵が安全な場所に保存されていることを知る必要があります。android_keystore_attestation 証明書タイプ(OpenID4VCI で使用する形式)は、Android キーストアからハードウェア署名付きレポートを提供し、鍵が高信頼実行環境(TEE)または StrongBox にロックされ、エクスポートまたは複製できないようにします。

ハードウェア構成証明の概要

Android キーストアで鍵が生成されると、システムは構成証明書を生成できます。この証明書は、デバイスのハードウェアによって保護された鍵で署名され、Google が保持するルート オブ トラストにチェーンバックされます。

android_keystore_attestation プルーフは、X.509 証明書チェーンの配列です。各チェーンは単一の認証鍵を表し、リーフ証明書と中間証明書で構成されています。

  • リーフ証明書: 鍵と Android 固有の構成証明拡張が含まれています。
  • 中間証明書: リーフを Android ルートに接続します。

確認手順

発行者は、証明書に対して複数の検証を行う必要があります。

  • Android 構成証明拡張データを含むチェーン内の証明書(通常はリーフ証明書)を見つけます。この証明書には、Android キーストアで生成された鍵の認証データが含まれています。
  • 拡張機能の attestationChallenge フィールドが、プロトコルによって提供された c_nonce と一致していることを確認して、リプレイ攻撃を防ぎます。
  • 関心のある拡張機能のすべてのアサーションの値を確認します。
  • Android キーストア証明書に対して失効チェックを実行します。

構成証明証明書の値は、複数のソースから取得されます。

  • 発行者: 発行者によってさまざまな値が提供されます。最も一般的な値は、提示時にフィルタリングできるように、発行者のメタデータ形式で指定されます。
  • ホルダー: パッケージ名や署名などの値はホルダーから取得されます。これらは標準の発行手続きでは共有されず、所有者から個別に取得する必要があります。
  • Protocol: attestationChallenge を含む nonce などの値は、プロトコルから取得されます。

構成証明データの検証に関する詳細な手順については、次のリソースをご覧ください。

構成証明の証明形式

認証情報リクエストには、次の例のように 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

証明書拡張機能の userAuthType 値と noAuthRequired

選択された発行者: 発行者メタデータの user_auth_types フィールド

nonce

構成証明拡張機能の attestationChallenge

プロトコルから: VCI で説明されている nonce エンドポイントc_nonce

認定資格

なし

なし

status

なし

なし