Hardwaregestützte Attestierung für digitale Anmeldedaten implementieren

In einem typischen Ablauf für die Ausstellung digitaler Anmeldedaten gemäß der OpenID for Verifiable Credential Issuance (OpenID4VCI) specification muss ein Aussteller wissen, dass der Schlüssel in den zu signierenden Anmeldedaten an einem sicheren Ort gespeichert ist. Der android_keystore_attestation-Nachweistyp – ein Format für die Verwendung mit OpenID4VCI – bietet einen hardwarebasierten Bericht aus dem Android Keystore. So wird sichergestellt, dass der Schlüssel in einer Trusted Execution Environment (TEE) oder StrongBox gesperrt ist und nicht exportiert oder geklont werden kann.

Hardware-Attestierung – Übersicht

Wenn ein Schlüssel im Android-Keystore generiert wird, kann das System ein Attestzertifikat generieren. Dieses Zertifikat wird mit einem Schlüssel signiert, der durch die Hardware des Geräts geschützt ist und auf einen von Google verwalteten Root of Trust zurückgeht.

Der android_keystore_attestation-Nachweis ist ein Array von X.509-Zertifikatsketten. Jede Kette stellt einen einzelnen Authentifizierungsschlüssel dar und ist durch ein untergeordnetes Zertifikat gefolgt von Zwischenzertifikaten strukturiert.

  • Blattzertifikat: Enthält den Schlüssel und eine Android-spezifische Attestierungserweiterung.
  • Zwischenzertifikate: Verbinden Sie das Endzertifikat mit dem Android-Root-Zertifikat.

Bestätigungsschritte

Aussteller sollten mehrere Validierungen der Attestierung durchführen.

  • Suchen Sie in der Kette nach dem Zertifikat, das die Android-Attestierungserweiterung enthält (in der Regel das untergeordnete Zertifikat). Dieses Zertifikat enthält die Attestierungsdaten für den vom Android-Schlüsselspeicher generierten Schlüssel.
  • Prüfen Sie, ob das Feld attestationChallenge in der Erweiterung mit dem vom Protokoll bereitgestellten c_nonce übereinstimmt, um Replay-Angriffe zu verhindern.
enthalten.
  • Prüfen Sie den Wert aller Zusicherungen in den Erweiterungen, die Sie interessieren.
  • Führen Sie eine Widerrufsprüfung für die Android Keystore-Zertifikate durch.

Die Werte im Attestierungsnachweis stammen aus verschiedenen Quellen:

  • Aussteller:Der Aussteller stellt verschiedene Werte bereit. Die gängigsten werden im Metadatenformat des Ausstellers angegeben, um das Filtern bei der Präsentation zu ermöglichen.
  • Inhaber:Werte wie der Paketname und die Signatur stammen vom Inhaber. Diese werden nicht über Standardausstellungsverfahren weitergegeben und müssen unabhängig vom Inhaber eingeholt werden.
  • Protokoll:Werte wie die Nonce mit attestationChallenge stammen aus dem Protokoll.

Eine ausführlichere Anleitung zum Validieren der Attestierungsdaten finden Sie in den folgenden Ressourcen:

Format des Attestierungsnachweises

In einer Anmeldedatenanfrage ist der android_keystore_attestation-Nachweis im folgenden Beispiel enthalten:

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

Sie wird dann im proofs-Objekt einer Anmeldedatenanfrage gespeichert.

{
  "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 der Ausstellermetadaten

Ein Aussteller gibt die unterstützten Nachweistypen an, indem er das android_keystore_attestation-Objekt in das proof_types_supported-Objekt für eine bestimmte Anmeldedatenkonfiguration einfügt.

Hier ist ein Beispiel für das android_keystore_attestation-Objekt für Aussteller:

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

Hier ein Beispiel für das äußere proof_types_supported-Objekt:

{
  "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-Attestierungsansprüche Android Keystore zuordnen

Diese Tabelle bietet eine informative Zuordnung, damit Rechtssubjekte, die mit dem standardmäßigen OpenID4VCI-Attestierungsbeweistyp vertraut sind, nachvollziehen können, wo sich ähnliche Konzepte in der Android Keystore-Attestierung befinden.

VCI-Attestierungsanspruch

android_keystore_attestation Standort

Standort des erwarteten Werts

iss

Öffentlicher Schlüssel des Root-Zertifikats des Schlüsselspeichers

iat

creationDateTime-Wert in der Attestierungserweiterung

exp

Feld validUntil im untergeordneten Zertifikat

attested_keys

Öffentlicher Schlüssel im Blattzertifikat jeder Kette

key_storage

keyMintSecurityLevel-Wert in der Attestierungserweiterung

Aussteller ausgewählt: Feld key_mint_security_level in den Ausstellermetadaten

user_authentication

userAuthType- und noAuthRequired-Werte in der Attestierungserweiterung

Aussteller ausgewählt: Feld user_auth_types in den Ausstellermetadaten

Nonce

attestationChallenge-Wert in der Attestierungserweiterung

Aus dem Protokoll: c_nonce-Wert aus dem Nonce-Endpunkt, der in VCI beschrieben wird

Zertifizierung

status