Hướng dẫn cho người mới bắt đầu sử dụng Verifier Registrar

Tổng quan

Phần này trình bày quy trình từng bước để các tổ chức đăng ký xác minh tham gia dịch vụ định danh của Google Wallet.

Là tổ chức đăng ký xác minh (ví dụ: công ty xác minh danh tính (IDV) xác minh thay mặt cho các thực thể khác), bạn đóng vai trò là Tổ chức 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 tin cậy cuối nguồn (RP) mà bạn quản lý.

Quy trình đăng ký

Bước 1: Gửi Biểu mẫu thu thập thông tin, 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 thu thập thông tin đăng ký dành cho Tổ chức đăng ký xác minh. Trong biểu mẫu này, bạn sẽ cung cấp cả Chứng chỉ gốc cho môi trường thử nghiệm và môi trường chính thức. Bằng cách gửi biểu mẫu thu thập thông tin đăng ký này, bạn cũng chính thức chấp nhận Điều khoản dịch vụ dành cho Tổ chức đăng ký xác minh của Google Wallet.

Bước 2: Tin cậy và kiểm thử trong môi trường thử nghiệm

Sau khi bạn gửi biểu mẫu thu thập thông tin, Google sẽ thêm chứng chỉ gốc cho môi trường thử nghiệm vào kho lưu trữ uy tín trong môi trường thử nghiệm của Google Wallet và thông báo cho bạn. Sau đó, bạn có thể bắt đầu kiểm thử quy trình tích hợp trong môi trường thử nghiệm bằng các chứng chỉ do gốc môi trường thử nghiệm của bạn ký.

Bước 3: Ghi lại video minh hoạ quy trình từ đầu đến cuối

Khi quá trình kiểm thử trong môi trường thử nghiệm 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 video minh hoạ cho cả quy trình do tổ chức xác minh lưu trữ (tự lưu trữ) và quy trình do người bán lưu trữ (do Bên tin cậy lưu trữ) (nếu có).
    • Sử dụng thành phần hiển thị thực 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ổng 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 chứng chỉ gốc cho môi trường chính thức

Sau khi nhận được video minh hoạ quy trình từ đầu đến cuối, 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 cho môi trường chính thức. 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 Bên tin cậy cuối nguồn.

Bước 5: Tiếp tục đăng ký cho Bên tin cậy cuối

Đối với mỗi Bên tin cậy cuối mà bạn ký, bạn phải:

  • Thông báo cho Google: Sử dụng Biểu mẫu đăng ký khách hàng dành cho Tổ chức đăng ký xác minh để thông báo cho Google về Bên tin cậy mới và trường hợp sử dụng dự kiến của Bên tin cậy đó.
  • Định cấu hình siêu dữ liệu: Điền thông tin hiển thị của Bên tin cậy (Tên, Biểu trưng, URL Chính sách quyền riêng tư) và đặt Tên phân biệt (Chủ đề) 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 v3 tiêu chuẩn được tạo bằng P-256 / ECDSA và chứa 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 quan trọng.
  • Nội dung: Hàm băm SHA256 của RelyingPartyMetadataBytes, được mã hoá trong ASN.1 OCTET STRING.

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 xác thực OpenID4VP đã ký, hãy thêm siêu dữ liệu được mã hoá theo 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 lạm dụng: Google giám sát hoạt động lạm dụng của Bên tin cậy và sẽ thông báo cho bạn về mọi hành vi lạm dụng được phát hiện.
  • Thu hồi nhanh chóng: Bạn phải nhanh chóng thu hồi chứng chỉ cho các Bên tin cậy lạm dụng và xuất bản Danh sách thu hồi chứng chỉ (CRL) đã cập nhật.
  • Kiểm tra: Google duy trì nhật ký ẩn danh để đảm bảo các yêu cầu của Bên tin cậy khớp với trường hợp sử dụng đã đăng ký.

Các bước tiếp theo

Để bắt đầu đăng ký với tư cách là Tổ chức đăng ký xác minh, hãy điền và gửi Biểu mẫu thu thập thông tin đăng ký dành cho Tổ chức đăng ký xác minh. Để đăng ký cho các khách hàng cuối nguồn tiếp theo, hãy sử dụng Biểu mẫu đăng ký khách hàng dành cho Tổ chức đăng ký xác minh.

Để xem các câu hỏi thường gặp về quy trình đăng ký và tích hợp, hãy xem Câu hỏi thường gặp về Thông tin xác thực và danh tính kỹ thuật số.

Thông tin chi tiết về quy trình tích hợp dành cho Tổ chức đăng ký xác minh

Phần sau đây trình bày thông tin chi tiết về quy trình tích hợp kỹ thuật dành cho các Tổ chức đăng ký xác minh tích hợp với API Thông tin xác thực kỹ thuật số (bao gồm đị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 Bằng chứng không tiết lộ thông tin).

Định dạng và chức năng được hỗ trợ

Google Wallet hỗ trợ Thẻ căn cước điện tử dựa trên ISO mdoc.

Định dạng yêu cầu

Để yêu cầu thông tin xác thực 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 xác thực cụ thể hoặc nhiều thông tin xác thực trong một đối tượng dcql_query.

Ví dụ về yêu cầu JSON

Sau đây là mẫu yêu cầu requestJson mdoc để 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.
        }
      ]
}

Mã hoá yêu cầu

client_metadata chứa khoá công khai mã hoá cho mỗi yêu cầu. Bạn cần lưu trữ khoá riêng tư cho mỗi yêu cầu và sử dụng các khoá này để xác thực và cho phép 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 thông tin xác thực, bạn phải thêm 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 bên dưới). Trường này chứa siêu dữ liệu của bên tin cậy được mã hoá theo 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.

Thông tin xác thực 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": {
          "doctype_value": "org.iso.18013.5.1.mDL"  // this is for mDL. Use com.google.wallet.idcard.1 for ID pass
        },
        "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 xác thực đủ điều kiện

Sau đây là ví dụ về yêu cầu cho cả mDL và thẻ giấy tờ tuỳ thân. Người dùng có thể tiếp tục với một trong hai.

{
  "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": "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_sets : [
      {
        "options": [
          [ "mdl-request" ],
          [ "id_pass-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 xác thực danh tính được lưu trữ trong Google Wallet.

Yêu cầu đã ký

Yêu cầu đã ký (Yêu cầu uỷ quyền được bảo mật bằng JWT) gói gọn yêu cầu trình bày có thể xác minh của bạn bên trong Mã thông báo web JSON (JWT) được ký bằng mật mã bằ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 cho 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 bạn có:

  • Khoá riêng tư: Bạn cần có khoá riêng tư (ví dụ: ES256 Đường cong elip) để 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ó 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 chứng chỉ công khai của bạn đã được đăng ký với Google Wallet.

Logic xây dựng yêu cầu

Để xây dựng yêu cầu, bạn cần sử dụng khoá riêng tư và gói tải trọng trong 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 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 (beta):

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 đố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 Danh tính

Thay vì chỉ định các tham số riêng lẻ cho yêu cầu 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 chuỗi JSON trong CredentialOption. Trình quản lý thông tin xác thực sẽ truyền chuỗi JSON này cùng với các ví kỹ thuật số hiện có mà không cần kiểm tra nội dung của chuỗi JSON đó. 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 danh tính. - Xác định thông tin xác thực đã 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 quy trình tích hợp ứng dụng Android.

Bạn sẽ 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 xác thực

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 và 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 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ẽ truyề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ể xem các bước để xác thực phản hồi thông tin xác thực

Web

Để yêu cầu Thông tin xác thực danh tính bằng API Thông tin xác thực kỹ thuật số trên Chrome hoặc các trình duyệt được hỗ trợ khác, hãy đưa ra 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 thông tin xác thực

Xác thực phản hồi

Sau khi ví trả về identityToken (JWT) được 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ã phản hồ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 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 JSON vp_token chứa thông tin xác thực

  {
    "vp_token":
    {
      "cred1": ["<base64UrlNoPadding_encoded_credential>"] // This applies to OpenID4VP 1.0 spec.
    }
  }
  1. Tạo bản chép lời phiên

    Bước tiếp theo là tạo SessionTranscript từ ISO/IEC 18013-5:2021 với cấu trúc Bàn giao cụ thể cho Android hoặc Web:

    SessionTranscript = [
      null,                // DeviceEngagementBytes not available
      null,                // EReaderKeyBytes not available
      [
        "OpenID4VPDCAPIHandover",
        AndroidHandoverDataBytes   // BrowserHandoverDataBytes for Web
      ]
    ]
    

    Đối với cả quy trình bàn giao trên Android và web, bạn 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.

    Bàn giao trên Android

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

    Bàn giao trên 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 thiết bị phải được xác thực theo điều khoản 9 của ISO/IEC 18013-5:2021.

    Quy trình xác thực này bao gồm một số bước:

  2. 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ừ issuerAuth và xác thực chuỗi chứng chỉ đó dựa trên chứng chỉ gốc IACA đáng tin cậy. Tham khảo chứng chỉ IACA của tổ chức phát hành được hỗ trợ.

  3. Xác minh chữ ký MSO (Phần 9.1.2 của 18013-5)

  4. Tính toán và kiểm tra ValueDigests cho các Phần tử dữ liệu (Phần 9.1.2 của 18013-5)

  5. Xác minh chữ ký deviceSignature (Phần 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ợ Bằng chứng không tiết lộ thông tin (ví dụ: xác minh rằng người dùng trên 18 tuổi mà không 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.

Để xem thông tin tổng quan về ZKP và các chức năng của ZKP, hãy xem 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 bằng chứng không tiết lộ thông tin được 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 thư viện longfellow-zk của Google.

Dịch vụ xác minh chứa một máy chủ dựa trên Docker 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à hỗ trợ