In dieser Anleitung wird beschrieben, wie Sie mit der DigitalCredential API bestätigte Telefonnummern für Ihre Nutzer abrufen. Der Prozess umfasst zwei Schritte:
TS.43 tokenanfordern: Ihre Client-App (der „Bestätiger“) fordert ein temporäres TS.43-Token vom Gerät des Nutzers an. DasTS.43 tokenist ein vom Mobilfunkanbieter ausgestellter Berechtigungsnachweis, der die Identität des Nutzers darstellt.- Token gegen eine Telefonnummer eintauschen: Das Backend Ihrer App tauscht das
TS.43 tokenmit einem Aggregator oder Mobilfunkanbieter gegen die bestätigte Telefon nummer des Nutzers ein.
Kompatibilität mit Android-Versionen
Die API zur Bestätigung der Telefonnummer wird unter Android 10 (API-Level 29) und höher unterstützt.
Voraussetzungen
Um die Bestätigung der Telefonnummer mit der DigitalCredential API zu implementieren, benötigen Sie ein Konto bei einem Aggregator. Ein Aggregator interagiert mit Mobilfunkanbietern und stellt die erforderliche API-Oberfläche für Ihre App bereit, in der Regel als kostenpflichtiger Cloud-API-Endpunkt.
Außerdem müssen Sie Ihrem Gradle-Build-Skript die folgenden Abhängigkeiten hinzufügen:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0") implementation("androidx.credentials:credentials-play-services-auth:1.6.0") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0" implementation "androidx.credentials:credentials-play-services-auth:1.6.0" }
Implementierung
Der End-to-End-Prozess umfasst im Allgemeinen die folgenden Schritte:
- DCQL-Parameter (Digital Credential Query Language) von einem Aggregator anfordern: Rufen Sie einen oder mehrere Aggregatoren auf und fordern Sie eine Reihe von DCQL Parametern an. Mit DCQL können Sie die genauen digitalen Berechtigungsnachweise angeben, die Sie von jedem Aggregator benötigen.
OpenID4VP-Anfrage erstellen: Erstellen Sie im Backend Ihrer App die OpenID4VP-Anfrage und fügen Sie die DCQL-Parameter vom Aggregator hinzu. Senden Sie dann die OpenID4VP-Anfrage an Ihre Client-App.
Credential Manager API aufrufen: Verwenden Sie in Ihrer Client-App die Credential Manager API, um die OpenID4VP-Anfrage an das Betriebssystem zu senden. Als Antwort erhalten Sie ein OpenID4VP-Antwortobjekt mit dem
TS.43 Digital Credential. Dieser Berechtigungsnachweis ist verschlüsselt und kann nur vom zugehörigen Aggregator entschlüsselt werden. Nachdem Sie das Mobilfunkanbieter-Token erhalten haben, senden Sie die Antwort von Ihrer Client-App an das Backend der App.Antwort validieren: Validieren Sie im Backend Ihrer App die OpenID4VP-Antwort.
Gegen Telefonnummer eintauschen: Senden Sie im Backend Ihrer App den
TS.43 Digital Credentialan den Aggregator. Der Aggregator validiert den Berechtigungsnachweis und gibt die bestätigte Telefonnummer zurück.
DCQL-Parameter von einem Aggregator anfordern
Senden Sie im Backend Ihrer App eine Anfrage an den Aggregator für ein DCQL-Berechtigungsnachweisobjekt (Digital Credential Query Language). Geben Sie in Ihrer Anfrage eine Nonce und eine Anfrage-ID an. Der Aggregator gibt das DCQL-Berechtigungsnachweisobjekt zurück, das eine ähnliche Struktur wie das folgende hat:
{
// The credential ID is mapped to the request ID that is sent in your request to the aggregator.
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
}
OpenID4VP-Anfrage erstellen
Erstellen Sie zuerst im Backend Ihrer App ein dcql_query-Objekt, indem Sie das DCQL-Berechtigungsnachweisobjekt in ein credentials-Array einfügen, das in einem dcql_query-Objekt verschachtelt ist, wie im folgenden Beispiel gezeigt:
"dcql_query": {
"credentials": [
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
]
}
Erstellen Sie dann eine OpenID4VP-Anfrage mit der folgenden Struktur:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
protocol: Muss für Anfragen zur Bestätigung der Telefonnummer aufopenid4vp-v1-unsignedgesetzt sein.response_typeundresponse_mode: Konstanten, die das Format der Anfrage mit den festen Wertenvp_tokenbzw.dc_apiangeben.nonce: Ein eindeutiger Wert, der von Ihrem Backend für jede Anfrage generiert wird. Die Nonce im DCQL-Berechtigungsnachweisobjekt des Aggregators muss mit dieser Nonce übereinstimmen.dcql_query: In diesem Fall geben Sie mitdcql_queryan, dass einTS.43 Digital Credentialangefordert wird. Sie können hier auch andere digitale Berechtigungsnachweise anfordern.
Umschließen Sie dann die OpenID4VP-Anfrage in ein DigitalCredential API-Anfrageobjekt und senden Sie sie an die Client-App.
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
Das folgende Snippet zeigt, wie die DigitalCredential API-Anfrage generiert wird:
def GenerateDCRequest():
credentials = []
aggregator1_dcql = call_aggregator_endpoint(nonce, "aggregator1", additional_params)
credentials.append(aggregator1_dcql) # You can optionally work with multiple
# aggregators, or request other types of credentials
val dc_request =
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": {"credentials": credentials}
}
}
]
}
return dc_request
Credential Manager API aufrufen
Rufen Sie in Ihrer Client-App die Credential Manager API mit der DigitalCredential API-Anfrage auf, die vom Backend Ihrer App bereitgestellt wird.
val requestJson = generateTs43DigitalCredentialRequestFromServer()
val digiCredOption = GetDigitalCredentialOption(requestJson = requestJson)
val getCredRequest = GetCredentialRequest(
listOf(digiCredOption)
)
coroutineScope.launch {
try {
val response = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
val credential = response.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
} catch (e : GetCredentialException) {
// If user cancels the operation, the feature isn't available, or the
// SIM doesn't support the feature, a GetCredentialCancellationException
// will be returned. Otherwise, a GetCredentialUnsupportedException will
// be returned with details in the exception message.
handleFailure(e)
}
}
Die DigitalCredential API-Antwort enthält die OpenID4VP-Antwort. Ein typisches
JSON-Objekt für Berechtigungsnachweise aus dem DigitalCredential Ergebnis sieht so aus:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
Senden Sie die DigitalCredential API-Antwort von Ihrer Client-App zurück an den Backend-Server, wo sie validiert und gegen die bestätigte Telefonnummer bei einem Aggregator eingetauscht werden kann.
In einigen Fällen kann die Antwort einen TS.43-Fehler enthalten. Die Fehlerantwort ist ein JSON-Objekt im OpenID4VP-Fehlerantwortformat:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"error": "<error_code>",
"error_description": "<Human-readable description of the error>",
}
}
Es gibt zwei mögliche error_code-Werte:
invalid_request: Gibt an, dass die Anfrage fehlerhaft war.server_error: Gibt an, dass bei der Verarbeitung der Anfrage Fehler aufgetreten sind. Das können lokale Fehler oder TS.43-Probleme sein.
Das Feld error_description enthält zusätzliche Details zum Problem.
Antwort des digitalen Berechtigungsnachweises validieren
Im Folgenden sehen Sie ein Beispiel dafür, wie Sie die Antwort parsen und den Validierungsschritt im Backend Ihrer App ausführen:
def processDigitalCredentialsResponse(response):
# Step 1: Parse out the TS.43 Digital Credential from the response
openId4VpResponse = response['data']
ts43_digital_credential = response['vp_token']["aggregator1"][0]
# Step 2: Perform response validation
verifyResponse(ts43_digital_credential)
def verifyResponse(ts43_digital_credential):
# The returned ts43_digital_credential is an SD-JWT-based Verifiable Credentials
# (SD-JWT VC) as defined in this IETF spec. The section 3.4 of the specification
# outlines how to validate the credential. At a high level, the steps involves
# validating (1) the nonce in the response credential matches the one in the
# request, (2) the integrity of the credential by checking the credential is
# signed by the trusted issuer Android Telephony, and (3) other validity
# properties associated with this credential, such as issue time and expiration
# time
# In most cases, you can use an SD-JWT VC library to perform these validations.
# Some aggregators may also perform the validation logic for you. Check with your
# aggregator to decide the exact scope of the validation required.
Gegen Telefonnummer eintauschen
Senden Sie im Backend Ihrer App den validierten TS.43 Digital Credential an den Endpunkt des Aggregators, um den Berechtigungsnachweis zu validieren und die bestätigte Telefonnummer zu erhalten.
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)