डिजिटल क्रेडेंशियल को ऑनलाइन स्वीकार करना

इस गाइड में बताया गया है कि Relying Parties (RPs), Digital Credentials API को तकनीकी तौर पर कैसे इंटिग्रेट कर सकती हैं. इससे वे Android ऐप्लिकेशन और वेब पर, Google Wallet से मोबाइल ड्राइवर लाइसेंस (एमडीएल) और आईडी पास के लिए अनुरोध कर सकती हैं और उनकी पुष्टि कर सकती हैं.

देखें

रजिस्ट्रेशन की प्रोसेस और ज़रूरी शर्तें

प्रोडक्शन में लाइव होने से पहले, आपको Relying Party के ऐप्लिकेशन को Google के साथ रजिस्टर करना होगा.

  1. सैंडबॉक्स में टेस्ट करना: हमारे सैंडबॉक्स एनवायरमेंट और टेस्ट आईडी बनाने की सुविधा का इस्तेमाल करके, डेवलपमेंट तुरंत शुरू किया जा सकता है. टेस्टिंग के लिए, सेवा की शर्तें स्वीकार करना ज़रूरी नहीं है.
  2. जानकारी इकट्ठा करने वाला फ़ॉर्म सबमिट करना: आरपी के लिए, शामिल होने का फ़ॉर्म भरें. आम तौर पर, शामिल होने में तीन से पांच कामकाजी दिन लगते हैं. उपयोगकर्ताओं को सहमति वाली स्क्रीन पर, आपके प्रॉडक्ट का नाम और लोगो दिखेगा. इससे उन्हें यह समझने में मदद मिलेगी कि उनसे कौन डेटा का अनुरोध कर रहा है.
  3. सेवा की शर्तें स्वीकार करना: लाइव होने से पहले, आपको सेवा की शर्तों पर हस्ताक्षर करना होगा.

अपने ऐप्लिकेशन को ट्रैक करने या उन इलाकों से टेस्टिंग करने के बारे में सवाल पूछने के लिए जहां यह सुविधा उपलब्ध नहीं है, अक्सर पूछे जाने वाले सवाल देखें.

स्वीकार किए जाने वाले फ़ॉर्मैट और सुविधाएं

Google Wallet, आईएसओ एमडीओसी पर आधारित डिजिटल आईडी स्वीकार करता है.

अनुरोध का फ़ॉर्मैट तय करना

किसी भी वॉलेट से क्रेडेंशियल का अनुरोध करने के लिए, आपको OpenID4VP का इस्तेमाल करके, अपने अनुरोध का फ़ॉर्मैट तय करना होगा. आपके पास, एक ही dcql_query ऑब्जेक्ट में, खास क्रेडेंशियल या एक से ज़्यादा क्रेडेंशियल का अनुरोध करने का विकल्प होता है.

JSON फ़ॉर्मैट में अनुरोध का उदाहरण

यहां, Android डिवाइस या वेब पर किसी भी वॉलेट से पहचान के क्रेडेंशियल पाने के लिए, एमडीओसी requestJson अनुरोध का एक सैंपल दिया गया है.

{
      "requests" : [
        {
          "protocol": "openid4vp-v1-signed",
          "data": {<signed_credential_request>} // This is an object, shouldn't be a string.
        }
      ]
}

अनुरोध को एन्क्रिप्ट (सुरक्षित) करना

client_metadata में, हर अनुरोध के लिए एन्क्रिप्ट (सुरक्षित) करने की सार्वजनिक कुंजी शामिल होती है. आपको हर अनुरोध के लिए निजी कुंजियां सेव करनी होंगी. साथ ही, वॉलेट ऐप्लिकेशन से मिले टोकन की पुष्टि करने और उसे स्वीकार करने के लिए, इन कुंजियों का इस्तेमाल करना होगा.

requestJson में मौजूद credential_request पैरामीटर में ये फ़ील्ड शामिल होते हैं.

खास क्रेडेंशियल

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

अनुमति वाला कोई भी क्रेडेंशियल

यहां, एमडीएल और आईडी पास, दोनों के लिए अनुरोध का उदाहरण दिया गया है. उपयोगकर्ता, इनमें से किसी एक के साथ आगे बढ़ सकता है.

{
  "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
        ],
        "isserauth_alg_values": [
          -7
        ]
      }
    }
  }
}

Google Wallet में सेव किए गए, पहचान से जुड़े किसी भी क्रेडेंशियल से, स्वीकार किए जाने वाले किसी भी एट्रिब्यूट का अनुरोध किया जा सकता है.

हस्ताक्षर किए गए अनुरोध

हस्ताक्षर किए गए अनुरोध (JWT से सुरक्षित किए गए अनुमति के अनुरोध) में, पुष्टि किए जा सकने वाले प्रज़ेंटेशन के आपके अनुरोध को, क्रिप्टोग्राफ़िक तरीके से हस्ताक्षर किए गए JSON वेब टोकन (JWT) में शामिल किया जाता है. इसके लिए, पीकेआई इन्फ़्रास्ट्रक्चर का इस्तेमाल किया जाता है. इससे अनुरोध की अखंडता पक्की होती है और Google Wallet को आपकी पहचान की पुष्टि होती है.

ज़रूरी शर्तें

हस्ताक्षर किए गए अनुरोध के लिए, कोड में बदलाव करने से पहले, पक्का करें कि आपके पास ये चीज़ें हों:

  • निजी कुंजी: अनुरोध पर हस्ताक्षर करने के लिए, आपको एक निजी कुंजी (जैसे, Elliptic Curve ES256) की ज़रूरत होगी. इसे आपके सर्वर में मैनेज किया जाता है.
  • सर्टिफ़िकेट: आपको अपनी कुंजी के जोड़े से मिला, स्टैंडर्ड X.509 सर्टिफ़िकेट चाहिए.
  • रजिस्ट्रेशन: पक्का करें कि आपका सार्वजनिक सर्टिफ़िकेट, Google Wallet के साथ रजिस्टर हो. wallet-identity-rp-support@google.com पर हमारी सहायता टीम से संपर्क करें

अनुरोध बनाने का लॉजिक

अनुरोध बनाने के लिए, आपको अपनी निजी कुंजी का इस्तेमाल करना होगा. साथ ही, पेलोड को जेडब्ल्यूएस में रैप करना होगा.

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

एपीआई को ट्रिगर करना

एपीआई का पूरा अनुरोध, सर्वर साइड पर जनरेट किया जाना चाहिए. प्लैटफ़ॉर्म के हिसाब से, जनरेट किए गए JSON को नेटिव एपीआई में पास किया जाएगा.

इन-ऐप्लिकेशन (Android)

अपने Android ऐप्लिकेशन से, पहचान के क्रेडेंशियल का अनुरोध करने के लिए, यह तरीका अपनाएं:

डिपेंडेंसी अपडेट करना

अपने प्रोजेक्ट के build.gradle में, अपनी डिपेंडेंसी को Credential Manager (बीटा) का इस्तेमाल करने के लिए अपडेट करें:

dependencies {
    implementation("androidx.credentials:credentials:1.5.0-beta01")
    implementation("androidx.credentials:credentials-play-services-auth:1.5.0-beta01")
}

Credential Manager को कॉन्फ़िगर करना

CredentialManager ऑब्जेक्ट को कॉन्फ़िगर और शुरू करने के लिए, इस तरह का लॉजिक जोड़ें:

// Use your app or activity context to instantiate a client instance of CredentialManager.
val credentialManager = CredentialManager.create(context)

पहचान से जुड़े एट्रिब्यूट का अनुरोध करना

पहचान के अनुरोधों के लिए, अलग-अलग पैरामीटर तय करने के बजाय, ऐप्लिकेशन उन सभी को CredentialOption में JSON स्ट्रिंग के तौर पर एक साथ उपलब्ध कराता है. Credential Manager, इस JSON स्ट्रिंग को उपलब्ध डिजिटल वॉलेट में पास करता है. इसके लिए, वह इसके कॉन्टेंट की जांच नहीं करता. इसके बाद, हर वॉलेट की यह ज़िम्मेदारी होती है कि वह: - पहचान के अनुरोध को समझने के लिए, JSON स्ट्रिंग को पार्स करे. - यह तय करे कि उसके सेव किए गए क्रेडेंशियल में से कौनसे क्रेडेंशियल, अनुरोध को पूरा करते हैं.

हमारा सुझाव है कि पार्टनर, Android ऐप्लिकेशन इंटिग्रेशन के लिए भी अपने अनुरोध सर्वर पर बनाएं.

`GetDigitalCredentialOption()` फ़ंक्शन कॉल में, `request` के तौर पर, `अनुरोध के फ़ॉर्मैट ` में मौजूद `requestJson` का इस्तेमाल किया जाएगा.

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

क्रेडेंशियल के जवाब को मैनेज करना

वॉलेट से जवाब मिलने के बाद, यह पुष्टि की जाएगी कि जवाब सही है या नहीं. साथ ही, यह भी देखा जाएगा कि इसमें credentialJson जवाब शामिल है या नहीं.

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

credentialJson जवाब में, W3C की ओर से तय किया गया, एन्क्रिप्ट (सुरक्षित) किया गया identityToken (JWT) शामिल होता है. इस जवाब को तैयार करने की ज़िम्मेदारी, Wallet ऐप्लिकेशन की होती है.

उदाहरण:

{
  "protocol" : "openid4vp-v1-signed",
  "data" : {
    <encrpted_response>
  }
}

इस जवाब को वापस सर्वर पर पास किया जाएगा, ताकि इसकी पुष्टि की जा सके. क्रेडेंशियल के जवाब की पुष्टि करने का तरीका यहां दिया गया है

वेब

Chrome या Digital Credentials API के साथ काम करने वाले अन्य ब्राउज़र पर, पहचान के क्रेडेंशियल का अनुरोध करने के लिए, यह अनुरोध करें.

const credentialResponse = await navigator.credentials.get({
          digital : {
          requests : [
            {
              protocol: "openid4vp-v1-signed",
              data: {<credential_request>} // This is an object, shouldn't be a string.
            }
          ]
        }
      })

क्रेडेंशियल के जवाब की पुष्टि करने के लिए, इस एपीआई से मिले जवाब को वापस अपने सर्वर पर भेजें

जवाब की पुष्टि करना

वॉलेट से एन्क्रिप्ट (सुरक्षित) किया गया identityToken (JWT) मिलने के बाद, डेटा पर भरोसा करने से पहले, सर्वर साइड पर इसकी पुष्टि करना ज़रूरी है.

जवाब को डिक्रिप्ट करना

जेडब्ल्यूई को डिक्रिप्ट करने के लिए, अनुरोध के client_metadata में भेजी गई सार्वजनिक कुंजी से जुड़ी निजी कुंजी का इस्तेमाल करें. इससे vp_token मिलता है.

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 से, क्रेडेंशियल वाला vp_token JSON मिलेगा

  {
    "vp_token":
    {
      "cred1": ["<base64UrlNoPadding_encoded_credential>"] // This applies to OpenID4VP 1.0 spec.
    }
  }
  1. सेशन की ट्रांसक्रिप्ट बनाना

    अगला चरण, आईएसओ/आईईसी 18013-5:2021 से SessionTranscript बनाना है. इसके लिए, Android या वेब के हिसाब से हैंडओवर स्ट्रक्चर का इस्तेमाल करें:

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

    Android और वेब, दोनों के हैंडओवर के लिए, आपको वही नॉनस इस्तेमाल करना होगा जिसका इस्तेमाल credential_request जनरेट करने के लिए किया गया था.

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

    ब्राउज़र हैंडओवर

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

    SessionTranscript का इस्तेमाल करके, डिवाइस के जवाब की पुष्टि, आईएसओ/आईईसी 18013-5:2021 के क्लॉज़ 9 के मुताबिक की जानी चाहिए.

    इस पुष्टि में कई चरण शामिल हैं:

  2. जारी करने वाली संस्था का सर्टिफ़िकेट देखना: issuerAuth से, जारी करने वाली संस्था के हस्ताक्षर करने वाले सर्टिफ़िकेट की चेन एक्सट्रैक्ट करें और इसकी पुष्टि, भरोसेमंद आईएसीए के रूट सर्टिफ़िकेट के ख़िलाफ़ करें. जारी करने वाली संस्था के आईएसीए के स्वीकार किए जाने वाले सर्टिफ़िकेट देखें.

  3. एमएसओ के हस्ताक्षर की पुष्टि करना (18013-5 सेक्शन 9.1.2)

  4. डेटा एलिमेंट के लिए ValueDigests की गिनती करना और उसकी जांच करना (18013-5 सेक्शन 9.1.2)

  5. deviceSignature के हस्ताक्षर की पुष्टि करना (18013-5 सेक्शन 9.1.3)

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

निजता बनाए रखते हुए, उम्र की पुष्टि करना (ZKP)

ज़ीरो-नॉलेज प्रूफ़ (जैसे, उपयोगकर्ता की सही जन्म तारीख देखे बिना यह पुष्टि करना कि उसकी उम्र 18 साल से ज़्यादा है) की सुविधा देने के लिए, अपने अनुरोध के फ़ॉर्मैट को mso_mdoc_zk में बदलें. साथ ही, ज़रूरी zk_system_type कॉन्फ़िगरेशन उपलब्ध कराएं.

ज़ीरो-नॉलेज प्रूफ़ (ZKP) क्या है और इसकी सुविधाओं के बारे में खास जानकारी पाने के लिए, अक्सर पूछे जाने वाले सवाल देखें.

  ...
  "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
            {
              ...

आपको वॉलेट से, एन्क्रिप्ट (सुरक्षित) किया गया ज़ीरो-नॉलेज प्रूफ़ मिलेगा. Google की longfellow-zk लाइब्रेरी का इस्तेमाल करके, जारी करने वाली संस्था के आईएसीए सर्टिफ़िकेट के ख़िलाफ़ इस प्रूफ़ की पुष्टि की जा सकती है.

पुष्टि करने वाली सेवा में, डिप्लॉयमेंट के लिए तैयार, Docker पर आधारित सर्वर शामिल होता है. इसकी मदद से, जारी करने वाली संस्था के कुछ आईएसीए सर्टिफ़िकेट के ख़िलाफ़, जवाब की पुष्टि की जा सकती है.

आईएसीए के जारी करने वाले उन सर्टिफ़िकेट को मैनेज करने के लिए, certs.pem में बदलाव किया जा सकता है जिन पर आपको भरोसा करना है.

संसाधन और सहायता