Tổng quan
Phần này trình bày quy trình từng bước để các đơn vị đăng ký xác minh tham gia Dịch vụ nhận dạng của Google Wallet.
Là một đơn vị đăng ký xác minh (ví dụ: một công ty xác minh danh tính (IDV) xác minh thay mặt cho các pháp nhân khác), bạn đóng vai trò là Cơ quan cấp chứng chỉ (CA) của riêng mình, ký các yêu cầu xác minh danh tính cho các Bên phụ thuộc cuối nguồn (RP) mà bạn quản lý.
Quy trình giới thiệu
Bước 1: Gửi biểu mẫu tiếp nhận, chứng chỉ gốc và chấp nhận Điều khoản dịch vụ
Điền và gửi Biểu mẫu tham gia dành cho người xác minh và người đăng ký. Trong biểu mẫu này, bạn sẽ cung cấp cả Chứng chỉ gốc của Hộp cát và Chứng chỉ gốc của bản phát hành công khai. Bằng việc gửi biểu mẫu đăng ký tham gia này, bạn cũng chính thức chấp nhận Điều khoản dịch vụ của Google Wallet Verifier Registrar.
Bước 2: Độ tin cậy và thử nghiệm trong môi trường hộp cát
Sau khi bạn gửi biểu mẫu tiếp nhận, Google sẽ thêm chứng chỉ gốc của hộp cát vào kho lưu trữ đáng tin cậy của hộp cát Google Wallet và thông báo cho bạn. Sau đó, bạn có thể bắt đầu kiểm thử quá trình tích hợp trong Hộp cát bằng các chứng chỉ do gốc hộp cát của bạn ký.
Bước 3: Quay video minh hoạ quy trình từ đầu đến cuối
Khi quá trình kiểm thử trong hộp cát hoàn tất, hãy ghi lại video minh hoạ quy trình xác minh từ đầu đến cuối cho Bên tin cậy ban đầu (thứ nhất) và gửi cho Google.
- Yêu cầu đối với video:
- Ghi lại bản minh hoạ cho cả quy trình do đơn vị xác minh lưu trữ (tự lưu trữ) và do người bán lưu trữ (do RP lưu trữ) (nếu có).
- Sử dụng thành phần hiển thị thực tế của người bán (Tên, Biểu trưng, URL Điều khoản dịch vụ) và thành phần hiển thị của đơn vị tập hợp trong video.
- Minh hoạ rõ ràng giao diện người dùng và các màn hình khởi chạy quy trình xác minh.
Bước 4: Phê duyệt và tin cậy gốc sản xuất
Sau khi nhận được video minh hoạ toàn diện của bạn, Google sẽ kích hoạt quy trình xem xét và phê duyệt video, đồng thời bắt đầu quy trình tin cậy chứng chỉ gốc sản xuất. Sau khi cả hai quy trình này hoàn tất và được phê duyệt, bạn có thể bắt đầu ra mắt dịch vụ cho các Đối tác khu vực cuối nguồn.
Bước 5: Tiếp tục tham gia chương trình End RP
Đối với mỗi End RP mà bạn ký, bạn phải:
- Thông báo cho Google: Sử dụng Biểu mẫu tham gia của khách hàng là đơn vị đăng ký xác minh để thông báo cho Google về RP mới và trường hợp sử dụng dự kiến của RP đó.
- Định cấu hình siêu dữ liệu: Điền thông tin hiển thị của RP (Tên, Biểu trưng, URL Chính sách quyền riêng tư) và đặt một Tên riêng biệt (Đối tượng) duy nhất trên toàn cầu trong chứng chỉ của họ.
Quy cách kỹ thuật
A. Hồ sơ chứng chỉ
Các yêu cầu phải được ký bằng chứng chỉ X.509 phiên bản 3 tiêu chuẩn được tạo bằng P-256 / ECDSA và chứa một tiện ích tuỳ chỉnh của Google:
- OID tiện ích tuỳ chỉnh:
1.3.6.1.4.1.11129.10.1 - Mức độ nghiêm trọng: Không nghiêm trọng.
- Nội dung: Hàm băm SHA256 của
RelyingPartyMetadataBytes, được mã hoá trong mộtOCTET STRINGASN.1.
B. Lược đồ siêu dữ liệu (CBOR)
Siêu dữ liệu phải được mã hoá theo định dạng CBOR.
; in CDDL for CBOR encoding
; schemaVersion = "v1"
RelyingPartyMetadataBytes = #6.24(bstr .cbor RelyingPartyMetadata)
RelyingPartyMetadata = {
"schema_version": tstr,
"display": DisplayInfo,
"aggregator_info": DisplayInfo ; Optional: include to show your branding alongside the RP
}
DisplayInfo = {
"display_name": tstr,
"logo_uri": tstr, ; See brand guidelines link in following paragraph
"privacy_policy_uri": tstr
}
logo_uri phải tuân thủ Nguyên tắc sử dụng thương hiệu của Google Wallet.
C. Tích hợp OpenID4VP
Khi định dạng yêu cầu thông tin đăng nhập OpenID4VP đã ký, hãy thêm siêu dữ liệu được mã hoá base64url vào trường gw_rp_metadata_bytes bên trong đối tượng client_metadata (như minh hoạ trong mã yêu cầu mẫu ở phần sau).
Tuân thủ và thu hồi
- Giám sát hành vi sai trái: Google giám sát hoạt động RP độc hại và sẽ thông báo cho bạn về mọi hành vi sai trái được phát hiện.
- Thu hồi kịp thời: Bạn phải thu hồi kịp thời chứng chỉ của các RP có hành vi sai trái và xuất bản Danh sách thu hồi chứng chỉ (CRL) mới nhất.
- Kiểm tra: Google duy trì nhật ký ẩn danh để đảm bảo các yêu cầu RP khớp với trường hợp sử dụng đã đăng ký.
Các bước tiếp theo
Để bắt đầu quy trình tham gia với tư cách là Verifier Registrar, hãy điền thông tin và gửi Biểu mẫu đăng ký tham gia của Verifier Registrar. Để tích hợp các ứng dụng khách tiếp theo, hãy sử dụng Biểu mẫu tích hợp ứng dụng khách của Trình đăng ký trình xác minh.
Để xem các câu hỏi thường gặp về quy trình tham gia và tích hợp, hãy tham khảo Câu hỏi thường gặp về danh tính và thông tin đăng nhập kỹ thuật số.
Thông tin chi tiết về việc tích hợp Verifier Registrar
Phần sau đây trình bày thông tin chi tiết về việc tích hợp kỹ thuật cho các Trình xác minh đăng ký tích hợp với Digital Credentials API (bao gồm cả định dạng yêu cầu, mã hoá yêu cầu, kích hoạt API, xác thực phản hồi và triển khai Chứng minh không tiết lộ).
Định dạng và chức năng được hỗ trợ
Google Wallet hỗ trợ Giấy tờ tuỳ thân điện tử dựa trên mdoc theo tiêu chuẩn ISO.
- Thông tin đăng nhập được hỗ trợ: Bạn có thể xem các thông tin đăng nhập và thuộc tính được hỗ trợ.
- Các giao thức được hỗ trợ: OpenID4VP (Phiên bản 1.0).
- SDK Android tối thiểu: Android 9 (cấp độ API 28) trở lên.
- Hỗ trợ trình duyệt: Để xem danh sách đầy đủ các trình duyệt hỗ trợ Digital Credentials API, hãy tham khảo trang Hỗ trợ hệ sinh thái.
- Câu hỏi thường gặp: Nếu bạn có thắc mắc về danh sách các quốc gia được hỗ trợ và thời gian hỗ trợ các khu vực mới, hãy xem Câu hỏi thường gặp về thông tin đăng nhập và dữ liệu.
Định dạng yêu cầu
Để yêu cầu thông tin đăng nhập từ bất kỳ ví nào, bạn phải định dạng yêu cầu bằng OpenID4VP. Bạn có thể yêu cầu thông tin đăng nhập cụ thể hoặc nhiều thông tin đăng nhập trong một đối tượng dcql_query duy nhất.
Ví dụ về yêu cầu JSON
Sau đây là mẫu yêu cầu mdoc requestJson để lấy thông tin xác thực danh tính từ bất kỳ ví nào trên thiết bị Android hoặc web.
{
"requests" : [
{
"protocol": "openid4vp-v1-signed",
"data": {<signed_credential_request>} // This is an object, shouldn't be a string.
}
]
}
Yêu cầu mã hoá
client_metadata chứa khoá công khai mã hoá cho mỗi yêu cầu.
Bạn sẽ cần lưu trữ khoá riêng tư cho từng yêu cầu và sử dụng khoá đó để xác thực và uỷ quyền mã thông báo mà bạn nhận được từ ứng dụng ví.
Siêu dữ liệu OpenID4VP tích hợp
Khi định dạng yêu cầu về thông tin đăng nhập, bạn phải thêm trường gw_rp_metadata_bytes vào bên trong đối tượng client_metadata (như minh hoạ trong mã yêu cầu mẫu bên dưới). Trường này chứa siêu dữ liệu của bên đáng tin cậy được mã hoá Base64URL mà Google Wallet yêu cầu để xác minh danh tính của bạn và hiển thị thương hiệu của bạn cho người dùng.
Tham số credential_request trong requestJson chứa các trường sau.
Chứng chỉ cụ thể
{
"response_type": "vp_token",
"response_mode": "dc_api.jwt", // change this to dc_api if you want to demo with a non encrypted response.
"nonce": "1234",
"dcql_query": {
"credentials": [
{
"id": "cred1",
"format": "mso_mdoc",
"meta": {
// Use org.iso.18013.5.1.mDL for mDL,
// com.google.wallet.idcard.1 for ID pass, or
// org.iso.23220.photoid.1 for ID pass (using photo ID document type)
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
}
]
},
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
"kty": "EC",
"crv": "P-256",
"x": "pDe667JupOe9pXc8xQyf_H03jsQu24r5qXI25x_n1Zs",
"y": "w-g0OrRBN7WFLX3zsngfCWD3zfor5-NLHxJPmzsSvqQ",
"use": "enc",
"kid" : "1", // This is required
"alg" : "ECDH-ES", // This is required
}
]
},
"vp_formats_supported": {
"mso_mdoc": {
"deviceauth_alg_values": [
-7
],
"issuerauth_alg_values": [
-7
]
}
},
"gw_rp_metadata_bytes": "<base64url encoded metadata string>"
}
}
Mọi thông tin đăng nhập đủ điều kiện
Sau đây là yêu cầu mẫu cho mDL, giấy tờ tuỳ thân điện tử và giấy tờ tuỳ thân điện tử (sử dụng loại giấy tờ tuỳ thân có ảnh). Người dùng có thể tiếp tục với một trong hai lựa chọn.
{
"response_type": "vp_token",
"response_mode": "dc_api.jwt", // change this to dc_api if you want to demo with a non encrypted response.
"nonce": "1234",
"dcql_query": {
"credentials": [
{
"id": "mdl-request",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
},
{ // Credential type 2: ID pass
"id": "id_pass-request",
"format": "mso_mdoc",
"meta": {
"doctype_value": "com.google.wallet.idcard.1"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
},
{ // Credential type 3: ID pass (using photo ID document type)
"id": "photo_id-request",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.23220.photoid.1"
},
"claims": [
{
"path": [
"org.iso.23220.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.23220.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.23220.1",
"age_over_18"
],
"intent_to_retain": false
}
]
}
]
credential_sets : [
{
"options": [
[ "mdl-request" ],
[ "id_pass-request" ],
[ "photo_id-request" ]
]
}
]
},
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
"kty": "EC",
"crv": "P-256",
"x": "pDe667JupOe9pXc8xQyf_H03jsQu24r5qXI25x_n1Zs",
"y": "w-g0OrRBN7WFLX3zsngfCWD3zfor5-NLHxJPmzsSvqQ",
"use": "enc",
"kid" : "1", // This is required
"alg" : "ECDH-ES", // This is required
}
]
},
"vp_formats_supported": {
"mso_mdoc": {
"deviceauth_alg_values": [
-7
],
"issuerauth_alg_values": [
-7
]
}
},
"gw_rp_metadata_bytes": "<base64url encoded metadata string>"
}
}
Bạn có thể yêu cầu bất kỳ số lượng thuộc tính được hỗ trợ nào từ mọi thông tin nhận dạng được lưu trữ trong Google Wallet.
Yêu cầu đã ký
Yêu cầu đã ký (Yêu cầu uỷ quyền bảo mật JWT) gói yêu cầu trình bày có thể xác minh của bạn trong một mã thông báo web theo chuẩn JSON (JWT) được ký bằng mật mã bằng cách sử dụng cơ sở hạ tầng PKI của bạn, đảm bảo tính toàn vẹn của yêu cầu và chứng minh danh tính của bạn với Google Wallet.
Điều kiện tiên quyết
Trước khi triển khai các thay đổi về mã cho yêu cầu đã ký, hãy đảm bảo rằng bạn đã:
- Khoá riêng tư: Bạn cần có khoá riêng tư (ví dụ: Đường cong Elliptic
ES256) để ký yêu cầu được quản lý trong máy chủ của bạn. - Chứng chỉ: Bạn cần có một chứng chỉ X.509 tiêu chuẩn bắt nguồn từ cặp khoá của bạn.
- Đăng ký: Đảm bảo rằng chứng chỉ công khai của bạn đã được đăng ký với Google Wallet.
Logic tạo yêu cầu
Để tạo một yêu cầu, bạn cần sử dụng khoá riêng tư và gói tải trọng trong một JWS.
def construct_openid4vp_request(
doctypes: list[str],
requested_fields: list[dict],
nonce_base64: str,
jwe_encryption_public_jwk: jwk.JWK,
is_zkp_request: bool,
is_signed_request: bool,
state: dict,
origin: str
) -> dict:
# ... [Existing logic to build 'presentation_definition' and basic 'request_payload'] ...
# ------------------------------------------------------------------
# SIGNED REQUEST IMPLEMENTATION (JAR)
# ------------------------------------------------------------------
if is_signed_request:
try:
# 1. Load the Verifier's Certificate
# We must load the PEM string into a cryptography x509 object
verifier_cert_obj = x509.load_pem_x509_certificate(
CERTIFICATE.encode('utf-8'),
backend=default_backend()
)
# 2. Calculate Client ID (x509_hash)
# We calculate the SHA-256 hash of the DER-encoded certificate.
cert_der = verifier_cert_obj.public_bytes(serialization.Encoding.DER)
verifier_fingerprint_bytes = hashlib.sha256(cert_der).digest()
# Create a URL-safe Base64 hash (removing padding '=')
verifier_fingerprint_b64 = base64.urlsafe_b64encode(verifier_fingerprint_bytes).decode('utf-8').rstrip("=")
# Format the client_id as required by the spec
client_id = f'x509_hash:{verifier_fingerprint_b64}'
# 3. Update Request Payload with JAR specific fields
request_payload["client_id"] = client_id
# Explicitly set expected origins to prevent relay attacks
# Format for android origin: origin = android:apk-key-hash:<base64SHA256_ofAppSigningCert>
# Format for web origin: origin = <origin_url>
if origin:
request_payload["expected_origins"] = [origin]
# 4. Create Signed JWT (JWS)
# Load the signing private key
signing_key = jwk.JWK.from_pem(PRIVATE_KEY.encode('utf-8'))
# Initialize JWS with the JSON payload
jws_token = jws.JWS(json.dumps(request_payload).encode('utf-8'))
# Construct the JOSE Header
# 'x5c' (X.509 Certificate Chain) is critical: it allows the wallet
# to validate your key against the one registered in the console.
x5c_value = base64.b64encode(cert_der).decode('utf-8')
protected_header = {
"alg": "ES256", # Algorithm (e.g., ES256 or RS256)
"typ": "oauth-authz-req+jwt", # Standard type for JAR
"kid": "1", # Key ID
"x5c": [x5c_value] # Embed the certificate
}
# Sign the token
jws_token.add_signature(
key=signing_key,
alg=None,
protected=json_encode(protected_header)
)
# 5. Return the Request Object
# Instead of returning the raw JSON, we return the signed JWT string
# under the 'request' key.
return {"request": jws_token.serialize(compact=True)}
except Exception as e:
print(f"Error signing OpenID4VP request: {e}")
return None
# ... [Fallback for unsigned requests] ...
return request_payload
Kích hoạt API
Toàn bộ yêu cầu API phải được tạo phía máy chủ. Tuỳ thuộc vào nền tảng, bạn sẽ truyền JSON đã tạo vào các API nền tảng.
Trong ứng dụng (Android)
Để yêu cầu thông tin xác thực danh tính từ ứng dụng Android, hãy làm theo các bước sau:
Cập nhật phần phụ thuộc
Trong build.gradle của dự án, hãy cập nhật các phần phụ thuộc để sử dụng Trình quản lý thông tin xác thực (bản thử nghiệm):
dependencies {
implementation("androidx.credentials:credentials:1.5.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.5.0-beta01")
}
Định cấu hình Trình quản lý thông tin xác thực
Để định cấu hình và khởi tạo một đối tượng CredentialManager, hãy thêm logic tương tự như sau:
// Use your app or activity context to instantiate a client instance of CredentialManager.
val credentialManager = CredentialManager.create(context)
Yêu cầu thuộc tính nhận dạng
Thay vì chỉ định các tham số riêng lẻ cho yêu cầu về danh tính, ứng dụng sẽ cung cấp tất cả các tham số này cùng nhau dưới dạng một chuỗi JSON trong CredentialOption.
Trình quản lý thông tin xác thực sẽ chuyển chuỗi JSON này đến các ví điện tử hiện có mà không kiểm tra nội dung của chuỗi. Sau đó, mỗi ví sẽ chịu trách nhiệm:
– Phân tích cú pháp chuỗi JSON để hiểu yêu cầu về danh tính.
– Xác định thông tin đăng nhập đã lưu trữ nào (nếu có) đáp ứng yêu cầu.
Các đối tác nên tạo yêu cầu trên máy chủ ngay cả đối với các hoạt động tích hợp ứng dụng Android.
Bạn sẽ dùng requestJson từ Định dạng yêu cầu làm request trong lệnh gọi hàm GetDigitalCredentialOption().
// The request in the JSON format to conform with
// the JSON-ified Digital Credentials API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
GetDigitalCredentialOption(requestJson = requestJson)
// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
listOf(digitalCredentialOption)
)
coroutineScope.launch {
try {
val result = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
verifyResult(result)
} catch (e : GetCredentialException) {
handleFailure(e)
}
}
Xử lý phản hồi thông tin đăng nhập
Sau khi nhận được phản hồi từ ví, bạn sẽ xác minh xem phản hồi đó có thành công hay không và có chứa phản hồi credentialJson hay không.
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson) // make a server call to validate the response
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
}
// Handle failure.
fun handleFailure(e: GetCredentialException) {
when (e) {
is GetCredentialCancellationException -> {
// The user intentionally canceled the operation and chose not
// to share the credential.
}
is GetCredentialInterruptedException -> {
// Retry-able error. Consider retrying the call.
}
is NoCredentialException -> {
// No credential was available.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}
Phản hồi credentialJson chứa một identityToken (JWT) được mã hoá, do W3C xác định. Ứng dụng Wallet chịu trách nhiệm tạo phản hồi này.
Ví dụ:
{
"protocol" : "openid4vp-v1-signed",
"data" : {
<encrpted_response>
}
}
Bạn sẽ chuyển phản hồi này trở lại máy chủ để xác thực tính xác thực của phản hồi. Bạn có thể tìm thấy các bước xác thực phản hồi về thông tin đăng nhập
Web
Để yêu cầu Thông tin xác thực danh tính bằng Digital Credentials API trên Chrome hoặc các trình duyệt được hỗ trợ khác, hãy gửi yêu cầu sau.
const credentialResponse = await navigator.credentials.get({
digital : {
requests : [
{
protocol: "openid4vp-v1-signed",
data: {<credential_request>} // This is an object, shouldn't be a string.
}
]
}
})
Gửi phản hồi từ API này trở lại máy chủ của bạn để xác thực phản hồi về thông tin đăng nhập
Xác thực câu trả lời
Sau khi ví trả về identityToken (JWT) đã mã hoá, bạn phải thực hiện quy trình xác thực phía máy chủ nghiêm ngặt trước khi tin tưởng dữ liệu.
Giải mã câu trả lời
Sử dụng khoá riêng tư tương ứng với khoá công khai được gửi trong client_metadata của yêu cầu để giải mã JWE. Thao tác này sẽ tạo ra một vp_token.
Ví dụ về Python:
from jwcrypto import jwe, jwk
# Retrieve the Private Key from Datastore
reader_private_jwk = jwk.JWK.from_json(jwe_private_key_json_str)
# Save public key thumbprint for session transcript
encryption_public_jwk_thumbprint = reader_private_jwk.thumbprint()
# Decrypt the JWE encrypted response from Google Wallet
jwe_object = jwe.JWE()
jwe_object.deserialize(encrypted_jwe_response_from_wallet)
jwe_object.decrypt(reader_private_jwk)
decrypted_payload_bytes = jwe_object.payload
decrypted_data = json.loads(decrypted_payload_bytes)
decrypted_data sẽ tạo ra một JSON vp_token chứa thông tin đăng nhập
{
"vp_token":
{
"cred1": ["<base64UrlNoPadding_encoded_credential>"] // This applies to OpenID4VP 1.0 spec.
}
}
Tạo bản chép lời của phiên
Bước tiếp theo là tạo SessionTranscript từ ISO/IEC 18013-5:2021 bằng cấu trúc Bàn giao dành riêng cho Android hoặc Web:
SessionTranscript = [ null, // DeviceEngagementBytes not available null, // EReaderKeyBytes not available [ "OpenID4VPDCAPIHandover", AndroidHandoverDataBytes // BrowserHandoverDataBytes for Web ] ]Đối với cả hoạt động bàn giao trên Android và web, bạn sẽ cần sử dụng cùng một số chỉ dùng một lần mà bạn đã dùng để tạo
credential_request.Android Handover
AndroidHandoverData = [ origin, // "android:apk-key-hash:<base64SHA256_ofAppSigningCert>", nonce, // nonce that was used to generate credential request, encryption_public_jwk_thumbprint, // Encryption public key (JWK) Thumbprint ] AndroidHandoverDataBytes = hashlib.sha256(cbor2.dumps(AndroidHandoverData)).digest()
Chuyển giao trình duyệt
BrowserHandoverData =[ origin, // Origin URL nonce, // nonce that was used to generate credential request encryption_public_jwk_thumbprint, // Encryption public key (JWK) Thumbprint ] BrowserHandoverDataBytes = hashlib.sha256(cbor2.dumps(BrowserHandoverData)).digest()
Khi sử dụng
SessionTranscript, Phản hồi của thiết bị phải được xác thực theo điều khoản 9 của tiêu chuẩn ISO/IEC 18013-5:2021.Quy trình xác thực này bao gồm một số bước:
Kiểm tra Chứng chỉ của tổ chức phát hành: Trích xuất chuỗi chứng chỉ ký của tổ chức phát hành từ
issuerAuthvà xác thực chuỗi này dựa trên các chứng chỉ gốc IACA đáng tin cậy. Tham khảo các chứng chỉ IACA của tổ chức phát hành được hỗ trợ.Xác minh chữ ký MSO (18013-5 Phần 9.1.2)
Tính toán và kiểm tra
ValueDigestscho các Phần tử dữ liệu (18013-5 Phần 9.1.2)Xác minh chữ ký
deviceSignature(Mục 9.1.3 của 18013-5)
{
"version": "1.0",
"documents": [
{
"docType": "org.iso.18013.5.1.mDL",
"issuerSigned": {
"nameSpaces": {...}, // contains data elements
"issuerAuth": [...] // COSE_Sign1 w/ issuer PK, mso + sig
},
"deviceSigned": {
"nameSpaces": 24(<< {} >>), // empty
"deviceAuth": {
"deviceSignature": [...] // COSE_Sign1 w/ device signature
}
}
}
],
"status": 0
}
Xác minh độ tuổi đảm bảo quyền riêng tư (ZKP)
Để hỗ trợ Chứng minh không tiết lộ (ví dụ: xác minh rằng người dùng trên 18 tuổi mà không cần xem ngày sinh chính xác của họ), hãy thay đổi định dạng yêu cầu thành mso_mdoc_zk và cung cấp cấu hình zk_system_type bắt buộc.
Để biết thông tin tổng quan ở cấp cao về ZKP và các chức năng của ZKP, hãy xem phần Câu hỏi thường gặp.
...
"dcql_query": {
"credentials": [{
"id": "cred1",
"format": "mso_mdoc_zk",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
"zk_system_type": [
{
"system": "longfellow-libzk-v1",
"circuit_hash": "f88a39e561ec0be02bb3dfe38fb609ad154e98decbbe632887d850fc612fea6f", // This will differ if you need more than 1 attribute.
"num_attributes": 1, // number of attributes (in claims) this has can support
"version": 5,
"block_enc_hash": 4096,
"block_enc_sig": 2945,
}
{
"system": "longfellow-libzk-v1",
"circuit_hash": "137e5a75ce72735a37c8a72da1a8a0a5df8d13365c2ae3d2c2bd6a0e7197c7c6", // This will differ if you need more than 1 attribute.
"num_attributes": 1, // number of attributes (in claims) this has can support
"version": 6,
"block_enc_hash": 4096,
"block_enc_sig": 2945,
}
],
"verifier_message": "challenge"
},
"claims": [{
...
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
...
Bạn sẽ nhận được một bằng chứng không tiết lộ thông tin đã mã hoá từ ví. Bạn có thể xác thực bằng chứng này dựa trên chứng chỉ IACA của tổ chức phát hành bằng cách sử dụng thư viện longfellow-zk của Google.
verifier-service chứa một máy chủ dựa trên Docker và sẵn sàng triển khai, cho phép bạn xác thực phản hồi dựa trên một số chứng chỉ IACA của tổ chức phát hành.
Bạn có thể sửa đổi certs.pem để quản lý các chứng chỉ của tổ chức phát hành IACA mà bạn muốn tin cậy.
Tài nguyên và dịch vụ hỗ trợ
- Câu hỏi thường gặp: Để biết các câu hỏi thường gặp về việc tích hợp kỹ thuật, hãy xem Câu hỏi thường gặp về danh tính và thông tin đăng nhập kỹ thuật số.
- Triển khai tham chiếu: Hãy xem Triển khai tham chiếu Trình xác minh danh tính của chúng tôi trên GitHub.
- Trang web thử nghiệm: Hãy thử quy trình từ đầu đến cuối tại verifier.multipaz.org.
- Quy cách OpenID4VP: Xem quy cách kỹ thuật cho openID4VP.
- Hỗ trợ: Để được trợ giúp gỡ lỗi hoặc giải đáp thắc mắc trong quá trình tích hợp, hãy liên hệ với
wallet-identity-rp-support@google.com.