Hướng dẫn này trình bày chi tiết cách sử dụng DigitalCredential API để lấy số điện thoại đã xác minh cho người dùng. Quy trình này bao gồm 2 bước:
- Yêu cầu
TS.43 token
: Ứng dụng khách của bạn ("trình xác minh") yêu cầu một mã thông báo TS.43 tạm thời từ thiết bị của người dùng.TS.43 token
là thông tin đăng nhập do nhà mạng phát hành, đại diện cho danh tính của người dùng. - Trao đổi mã thông báo để lấy số điện thoại: Phần phụ trợ của ứng dụng sẽ trao đổi
TS.43 token
với một đơn vị tổng hợp hoặc nhà mạng để lấy số điện thoại đã xác minh của người dùng.
Điều kiện tiên quyết
Để triển khai quy trình xác minh số điện thoại bằng DigitalCredential API, bạn cần có một tài khoản với một đơn vị tổng hợp. Trình tổng hợp tương tác với các hãng vận chuyển và cung cấp nền tảng API cần thiết cho ứng dụng của bạn, thường là một điểm cuối API đám mây có tính phí.
Bạn cũng cần thêm các phần phụ thuộc sau đây vào tập lệnh bản dựng Gradle:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-alpha05") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-alpha05") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0-alpha05" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha05" }
Triển khai
Quy trình từ đầu đến cuối thường bao gồm các bước sau:
- Yêu cầu các tham số DCQL (Ngôn ngữ truy vấn thông tin đăng nhập kỹ thuật số) từ một đơn vị tổng hợp: Gọi một hoặc nhiều đơn vị tổng hợp và yêu cầu một tập hợp các tham số DCQL. DCQL cho phép bạn chỉ định chính xác thông tin đăng nhập kỹ thuật số mà bạn cần từ mỗi đơn vị tổng hợp.
Tạo yêu cầu OpenID4VP: Từ phần phụ trợ của ứng dụng, hãy tạo yêu cầu OpenID4VP, đồng thời thêm các thông số DCQL từ trình tổng hợp. Sau đó, hãy gửi yêu cầu OpenID4VP đến ứng dụng khách của bạn.
Gọi Credential Manager API: Trong ứng dụng khách, hãy dùng Credential Manager API để gửi yêu cầu OpenID4VP đến hệ điều hành. Để phản hồi, bạn sẽ nhận được một đối tượng phản hồi OpenID4VP chứa
TS.43 Digital Credential
. Thông tin xác thực này được mã hoá và chỉ có thể được giải mã bởi trình tổng hợp được liên kết. Sau khi nhận được mã thông báo của hãng vận chuyển, hãy gửi phản hồi từ ứng dụng khách đến máy chủ phụ trợ của ứng dụng.Xác thực phản hồi: Trong phần phụ trợ của ứng dụng, hãy xác thực phản hồi OpenID4VP.
Trao đổi số điện thoại: Từ phần phụ trợ của ứng dụng, hãy gửi
TS.43 Digital Credential
đến đơn vị tổng hợp. Trình tổng hợp xác thực thông tin đăng nhập và trả về số điện thoại đã xác minh.
Yêu cầu các tham số DCQL từ một đơn vị tổng hợp
Từ phần phụ trợ của ứng dụng, hãy gửi yêu cầu đến đơn vị tổng hợp để lấy một đối tượng thông tin đăng nhập bằng Ngôn ngữ truy vấn thông tin đăng nhập kỹ thuật số (DCQL). Hãy nhớ cung cấp một số chỉ dùng một lần và mã yêu cầu trong yêu cầu của bạn. Trình tổng hợp trả về đối tượng thông tin xác thực DCQL. Đối tượng này có cấu trúc tương tự như sau:
{
// 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"]
}
]
}
Tạo yêu cầu OpenID4VP
Trước tiên, từ phần phụ trợ của ứng dụng, hãy tạo một đối tượng dcql_query
bằng cách đặt đối tượng thông tin đăng nhập DCQL trong một mảng credentials
được lồng trong một đối tượng dcql_query
như minh hoạ trong ví dụ sau:
"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"]
}
]
]
}
Sau đó, hãy tạo một yêu cầu OpenID4VP có cấu trúc như sau:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
protocol
: Phải được đặt thànhopenid4vp-v1-unsigned
cho các yêu cầu xác minh số điện thoại.response_type
vàresponse_mode
: Hằng số biểu thị định dạng của yêu cầu với các giá trị cố định lần lượt làvp_token
vàdc_api
.nonce
: Một giá trị riêng biệt do phụ trợ của bạn tạo cho mỗi yêu cầu. Số chỉ dùng một lần trong đối tượng thông tin đăng nhập DCQL của đơn vị tổng hợp phải khớp với số chỉ dùng một lần này.dcql_query
: Trong trường hợp này, hãy sử dụngdcql_query
để chỉ định rằng bạn đang yêu cầu mộtTS.43 Digital Credential
. Bạn cũng có thể yêu cầu cấp thông tin đăng nhập kỹ thuật số khác tại đây.
Sau đó, hãy gói yêu cầu OpenID4VP trong một đối tượng yêu cầu DigitalCredential API rồi gửi đến ứng dụng khách.
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
Đoạn mã sau đây minh hoạ cách tạo yêu cầu DigitalCredential API:
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
Gọi Credential Manager API
Trong ứng dụng khách, hãy gọi Credential Manager API, cùng với yêu cầu DigitalCredential API do phần phụ trợ của ứng dụng cung cấp.
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)
}
}
Phản hồi của DigitalCredential API chứa phản hồi OpenID4VP. Sau đây là một tệp JSON thông tin đăng nhập điển hình từ kết quả DigitalCredential
:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
Từ ứng dụng khách, hãy gửi phản hồi của DigitalCredential API trở lại máy chủ phụ trợ để xác thực và dùng để trao đổi số điện thoại đã xác minh với một đơn vị tổng hợp.
Xác thực phản hồi của Thông tin xác thực kỹ thuật số
Sau đây là ví dụ về cách phân tích cú pháp phản hồi và thực hiện bước xác thực trong phần phụ trợ của ứng dụng:
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.
Trao đổi số điện thoại
Từ phần phụ trợ của ứng dụng, hãy gửi TS.43 Digital Credential
đã xác thực đến điểm cuối của trình tổng hợp để xác thực thông tin đăng nhập và nhận số điện thoại đã xác minh.
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)