Menerapkan pengesahan yang didukung hardware untuk kredensial digital

Dalam alur penerbitan kredensial digital yang umum menggunakan spesifikasi OpenID for Verifiable Credential Issuance (OpenID4VCI), penerbit perlu mengetahui bahwa kunci dalam kredensial yang akan ditandatangani disimpan di lokasi yang aman. Jenis bukti android_keystore_attestation—format untuk digunakan dengan OpenID4VCI—memberikan laporan yang ditandatangani hardware dari Android Keystore, sehingga memastikan kunci dikunci di Trusted Execution Environment (TEE) atau StrongBox dan tidak dapat diekspor atau dikloning.

Ringkasan pengesahan hardware

Saat kunci dibuat di Android Keystore, sistem dapat membuat sertifikat pengesahan. Sertifikat ini ditandatangani oleh kunci yang dilindungi oleh hardware perangkat, yang terhubung kembali ke Root of Trust yang dimiliki Google.

Bukti android_keystore_attestation adalah array rantai sertifikat X.509. Setiap rantai mewakili satu kunci autentikasi dan disusun oleh sertifikat leaf yang diikuti oleh sertifikat perantara.

  • Sertifikat leaf: Berisi kunci dan ekstensi pengesahan khusus Android.
  • Intermediate certificate: Menghubungkan leaf ke Root Android.

Langkah-langkah verifikasi

Penerbit harus melakukan beberapa validasi pada pengesahan.

  • Temukan sertifikat dalam rantai yang berisi ekstensi pengesahan Android (biasanya sertifikat entitas akhir). Sertifikat ini berisi data pengesahan untuk kunci yang dibuat oleh Android Keystore.
  • Pastikan kolom attestationChallenge di ekstensi cocok dengan c_nonce yang disediakan oleh protokol untuk mencegah serangan replay.
  • Verifikasi nilai semua pernyataan dalam ekstensi yang Anda minati.
  • Lakukan pemeriksaan pencabutan terhadap sertifikat Android Keystore.

Nilai dalam bukti pengesahan berasal dari beberapa sumber:

  • Penerbit: Berbagai nilai disediakan oleh penerbit, dan nilai yang paling umum dimasukkan dalam format metadata penerbit untuk memungkinkan pemfilteran saat presentasi.
  • Pemegang: Nilai seperti nama paket dan tanda tangan berasal dari pemegang. Kredensial ini tidak dibagikan melalui prosedur penerbitan standar dan harus diperoleh secara terpisah dari pemegangnya.
  • Protokol: Nilai seperti nonce dengan attestationChallenge berasal dari protokol.

Untuk mendapatkan petunjuk yang lebih lengkap tentang cara memvalidasi data pengesahan, lihat referensi berikut:

Format bukti pengesahan

Dalam permintaan kredensial, bukti android_keystore_attestation disertakan dalam contoh berikut:

{
  "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
}

Kemudian, nilai ini disimpan dalam objek proofs dari permintaan kredensial.

{
  "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
    ]
  }
}

Format metadata penerbit

Penerbit menunjukkan jenis bukti yang didukungnya dengan menyertakan objek android_keystore_attestation dalam objek proof_types_supported untuk konfigurasi kredensial tertentu.

Berikut adalah contoh objek android_keystore_attestation untuk penerbit:

{
  "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"]
}

Berikut adalah contoh objek proof_types_supported luar:

{
  "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"]
          }
        }
      }
    }
  }
}

Memetakan klaim pengesahan VCI ke Android Keystore

Tabel ini menyediakan pemetaan informasi untuk membantu entity yang memahami jenis bukti pengesahan OpenID4VCI standar memahami lokasi konsep serupa dalam pengesahan Android Keystore.

Klaim pengesahan VCI

Lokasi android_keystore_attestation

Lokasi nilai yang diharapkan

iss

Kunci publik sertifikat root Keystore

T/A

iat

Nilai creationDateTime di ekstensi pengesahan

T/A

exp

validUntil di sertifikat entitas akhir

T/A

attested_keys

Kunci publik yang ada dalam sertifikat leaf setiap rantai

T/A

key_storage

Nilai keyMintSecurityLevel di ekstensi pengesahan

Penerbit yang dipilih: kolom key_mint_security_level dalam metadata penerbit

user_authentication

Nilai userAuthType dan noAuthRequired di ekstensi pengesahan

Penerbit yang dipilih: kolom user_auth_types dalam metadata penerbit

nonce

Nilai attestationChallenge di ekstensi pengesahan

Dari protokol: Nilai c_nonce dari endpoint nonce yang dijelaskan dalam VCI

sertifikasi

T/A

T/A

status

T/A

T/A