Telefon numaralarını dijital kimlik bilgileriyle doğrulama

Bu kılavuzda, kullanıcılarınızın doğrulanmış telefon numaralarını almak için DigitalCredential API'nin nasıl kullanılacağı ayrıntılı olarak açıklanmaktadır. Bu işlem iki adımdan oluşur:

  1. TS.43 token isteğinde bulunma: İstemci uygulamanız ("doğrulayıcı"), kullanıcının cihazından geçici bir TS.43 jetonu ister. TS.43 token, kullanıcının kimliğini temsil eden, operatör tarafından verilen bir kimlik bilgisidir.
  2. Jetonu telefon numarasıyla değiştirme: Uygulamanızın arka ucu, TS.43 token ile kullanıcının doğrulanmış telefon numarasını almak için bir toplayıcı veya operatörle iletişim kurar.

Android sürümü uyumluluğu

Telefon Numarası Doğrulama API'si, Android 10 (API düzeyi 29) ve sonraki sürümlerde desteklenir.

Ön koşullar

Telefon numarası doğrulamasını DigitalCredential API ile uygulamak için bir toplayıcıda hesabınızın olması gerekir. Bir toplayıcı, operatörlerle etkileşime girer ve uygulamanız için gerekli API yüzeyini sağlar. Bu yüzey genellikle faturalandırılabilir bir bulut API uç noktasıdır.

Ayrıca, Gradle derleme komut dosyanıza aşağıdaki bağımlılıkları da eklemeniz gerekir:

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

Uygulama

Uçtan uca süreç genellikle şu adımları içerir:

  1. Toplayıcıdan DCQL (Dijital Kimlik Bilgisi Sorgu Dili) parametreleri isteyin: Bir veya daha fazla toplayıcıyı çağırın ve bir dizi DCQL parametresi isteyin. DCQL, her toplayıcıdan tam olarak hangi dijital kimlik bilgilerine ihtiyacınız olduğunu belirtmenize olanak tanır.
  2. OpenID4VP isteğini oluşturun: Uygulamanızın arka ucundan, toplayıcıdaki DCQL parametrelerini de ekleyerek OpenID4VP isteğini oluşturun. Ardından, OpenID4VP isteğini istemci uygulamanıza gönderin.

  3. Credential Manager API'sini çağırın: İstemci uygulamanızda, OpenID4VP isteğini işletim sistemine göndermek için Credential Manager API'sini kullanın. Buna karşılık olarak, TS.43 Digital Credential içeren bir OpenID4VP yanıt nesnesi alırsınız. Bu kimlik bilgisi şifrelenir ve yalnızca ilişkili toplayıcı tarafından şifresi çözülebilir. Operatör jetonunu aldıktan sonra, istemci uygulamanızdan gelen yanıtı uygulamanın arka ucuna gönderin.

  4. Yanıtı doğrulayın: Uygulamanızın arka ucunda OpenID4VP yanıtını doğrulayın.

  5. Telefon numarası karşılığında değişim: Uygulamanızın arka ucundan TS.43 Digital Credential değerini toplayıcıya gönderin. Toplayıcı, kimlik bilgisini doğrular ve doğrulanmış telefon numarasını döndürür.

Telefon numarası doğrulama isteğinin akışını gösteren resim
Şekil 1. Doğrulayıcı arka ucunun bir toplayıcıdan parametre istemesiyle başlayıp doğrulanmış bir telefon numarasının döndürülmesiyle sona eren telefon numarası doğrulama isteğinin yaşam döngüsü.

Toplayıcıdan DCQL parametreleri isteme

Uygulamanızın arka ucundan, toplayıcıya Digital Credential Query Language (DCQL) kimlik bilgisi nesnesi için istek gönderin. İsteğinizde nonce ve istek kimliği sağladığınızdan emin olun. Toplayıcı, aşağıdaki yapıya benzer bir yapıya sahip olan DCQL kimlik bilgisi nesnesini döndürür:

{
  // 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 isteğini oluşturma

Öncelikle, uygulamanızın arka ucundan, aşağıdaki örnekte gösterildiği gibi DCQL credential nesnesini bir dcql_query nesnesi içinde yerleştirerek bir dcql_query nesnesi oluşturun: credentials

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

Ardından, aşağıdaki yapıyla bir OpenID4VP isteği oluşturun:

{
  "protocol": "openid4vp-v1-unsigned",
  "data": {
    "response_type": "vp_token",
    "response_mode": "dc_api",
    "nonce": "...",
    "dcql_query": { ... }
  }
}
  • protocol: Telefon numarası doğrulama istekleri için openid4vp-v1-unsigned olarak ayarlanmalıdır.
  • response_type ve response_mode: Sabit değerler olan vp_token ve dc_api ile sırasıyla isteğin biçimini belirten sabitler.
  • nonce: Her istek için arka uçunuz tarafından oluşturulan benzersiz bir değer. Toplayıcı DCQL kimlik bilgisi nesnesindeki tek seferlik rastgele sayı, bu tek seferlik rastgele sayı ile eşleşmelidir.
  • dcql_query: Bu durumda, TS.43 Digital Credential istenildiğini belirtmek için dcql_query özelliğini kullanın. Diğer dijital kimlikleri de buradan isteyebilirsiniz.

Ardından, OpenID4VP isteğini DigitalCredential API istek nesnesine sarmalayın ve istemci uygulamasına gönderin.

{
  "requests":
    [
      {
        "protocol": "openid4vp-v1-unsigned",
        "data": {
          "response_type": "vp_token",
          "response_mode": "dc_api",
          "nonce": "...",
          "dcql_query": { ... }
        }
      }
    ]
}

Aşağıdaki snippet'te, DigitalCredential API isteğinin nasıl oluşturulacağı gösterilmektedir:

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'yi çağırma

İstemci uygulamanızda, uygulamanızın arka ucu tarafından sağlanan DigitalCredential API isteğiyle Credential Manager API'ye bir çağrı yapın.

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)
  }
}

DigitalCredential API yanıtı, OpenID4VP yanıtını içerir. DigitalCredential sonucundan alınan tipik bir kimlik bilgisi JSON'u aşağıdaki gibidir:

{
  "protocol": "openid4vp-v1-unsigned",

  "data": {
    "vp_token": {
      "aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
                                             # Credential in an array structure.
    }
  }
}

İstemci uygulamanızdan DigitalCredential API yanıtını, doğrulanabileceği ve toplayıcı ile doğrulanmış telefon numarası karşılığında kullanılabileceği arka uç sunucusuna geri gönderin.

Bazı durumlarda yanıtta TS.43 hatası olabilir. Hata yanıtı, OpenID4VP hata yanıtı biçimini izleyen bir JSON nesnesidir:

{
  "protocol": "openid4vp-v1-unsigned",

  "data": {
    "error": "<error_code>",
    "error_description": "<Human-readable description of the error>",
  }
}

2 olası error_code değeri vardır:

  • invalid_request: Bu, isteğin hatalı biçimlendirildiğini gösterir.
  • server_error: Bu, isteğin işlenmesi sırasında hatalar oluştuğunu gösterir. Bu durum yerel hatalardan veya TS.43 sorunlarından kaynaklanabilir.

error_description alanı, sorun hakkında ek ayrıntılar sağlar.

Dijital kimlik bilgisi yanıtını doğrulama

Aşağıda, yanıtın nasıl ayrıştırılacağı ve uygulamanızın arka ucunda doğrulama adımının nasıl gerçekleştirileceğine dair bir örnek verilmiştir:

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.

Telefon numarası için değişim

Uygulamanızın arka ucundan, kimlik bilgisini doğrulamak ve doğrulanmış telefon numarasını almak için doğrulanmış TS.43 Digital Credential değerini toplayıcının uç noktasına gönderin.

def processDigitalCredentialsResponse(response):
  # ... prior steps

  # Step 3: Call aggregator endpoint to exchange the verified phone number
  callAggregatorPnvEndpoint(ts43_digital_credential)