Telefon numaralarını dijital kimlik bilgileriyle doğrulama

Bu kılavuzda, kullanıcılarınız için doğrulanmış telefon numaraları almak üzere 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.

Ön koşullar

DigitalCredential API ile telefon numarası doğrulamasını 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-alpha05")
    implementation("androidx.credentials:credentials-play-services-auth:1.6.0-alpha05")
}

Eski

dependencies {
    implementation "androidx.credentials:credentials:1.6.0-alpha05"
    implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha05"
}

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. Kimlik Bilgisi Yöneticisi API'sini çağırın: İstemci uygulamanızda, OpenID4VP isteğini işletim sistemine göndermek için Kimlik Bilgisi Yöneticisi API'sini kullanın. Buna karşılık, 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 nonce, bu nonce ile eşleşmelidir.
  • dcql_query: Bu durumda, TS.43 Digital Credential istendiğ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.

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

Aşağıda, yanıtın nasıl ayrıştırılacağına 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 bilgilerini 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)