खास जानकारी
इस सेक्शन में, पुष्टि करने वाले रजिस्ट्रार के लिए, Google Wallet पहचान करने वाली सेवा के साथ जुड़ने की सिलसिलेवार प्रोसेस के बारे में बताया गया है.
पुष्टि करने वाले रजिस्ट्रार (उदाहरण के लिए, आईडीवी कंपनी जो अन्य इकाइयों की ओर से पुष्टि करती है) के तौर पर, आपके पास अपनी सर्टिफ़िकेट अथॉरिटी (सीए) होती है. यह सीए, आपके मैनेज किए जा रहे डाउनस्ट्रीम एंड रिलाइंग पार्टी (आरपी) के लिए, पहचान की पुष्टि करने के अनुरोधों पर हस्ताक्षर करता है.
शामिल होने की प्रोसेस
पहला चरण: इंटेक फ़ॉर्म और रूट सर्टिफ़िकेट सबमिट करना. साथ ही, सेवा की शर्तों को स्वीकार करना
सर्टिफ़िकेट जारी करने वाली संस्था के तौर पर शामिल होने के लिए, वेरिफ़ायर रजिस्ट्रार का ऑनबोर्डिंग इनटेक फ़ॉर्म भरें और सबमिट करें. इस फ़ॉर्म में, आपको सैंडबॉक्स और प्रोडक्शन रूट सर्टिफ़िकेट, दोनों देने होंगे. इस ऑनबोर्डिंग इंटेक फ़ॉर्म को सबमिट करने का मतलब है कि आपने Google Wallet Verifier Registrar की सेवा की शर्तों को भी स्वीकार कर लिया है.
दूसरा चरण: सैंडबॉक्स पर भरोसा करना और उसकी टेस्टिंग करना
इंटेक फ़ॉर्म सबमिट करने के बाद, Google आपके सैंडबॉक्स रूट सर्टिफ़िकेट को Google Wallet के सैंडबॉक्स ट्रस्ट स्टोर में जोड़ देता है. साथ ही, आपको इसकी सूचना देता है. इसके बाद, सैंडबॉक्स रूट से साइन किए गए सर्टिफ़िकेट का इस्तेमाल करके, सैंडबॉक्स में इंटिग्रेशन की टेस्टिंग शुरू की जा सकती है.
तीसरा चरण: E2E वीडियो डेमो रिकॉर्ड करना
सैंडबॉक्स टेस्टिंग पूरी होने के बाद, पुष्टि करने के फ़्लो के शुरू से आखिर तक के वीडियो डेमो रिकॉर्ड करें. ये डेमो, पहले (पहले) रिलाइंग पार्टी के लिए होने चाहिए. इसके बाद, इन्हें Google को सबमिट करें.
- वीडियो के लिए ज़रूरी शर्तें:
- लागू होने पर, पुष्टि करने वाले व्यक्ति के होस्ट किए गए (सेल्फ़-होस्ट किए गए) और कारोबारी या कंपनी के होस्ट किए गए (आरपी-होस्ट किए गए), दोनों फ़्लो के लिए प्रदर्शन रिकॉर्ड करें.
- वीडियो में कारोबारी या कंपनी की डिसप्ले ऐसेट (नाम, लोगो, सेवा की शर्तों का यूआरएल) और एग्रीगेटर की डिसप्ले ऐसेट का इस्तेमाल करें.
- यूज़र इंटरफ़ेस और पुष्टि करने की प्रोसेस शुरू करने वाली स्क्रीन को साफ़ तौर पर दिखाएं.
चौथा चरण: मंज़ूरी और प्रोडक्शन रूट ट्रस्टिंग
वीडियो में पूरी प्रोसेस दिखाने के बाद, Google वीडियो की समीक्षा और मंज़ूरी देने की प्रोसेस शुरू करता है. साथ ही, प्रोडक्शन रूट सर्टिफ़िकेट की पुष्टि करने की प्रोसेस भी शुरू करता है. दोनों प्रोसेस पूरी होने और उन्हें मंज़ूरी मिलने के बाद, डाउनस्ट्रीम एंड आरपी के लिए सेवा लॉन्च की जा सकती है.
पांचवां चरण: एंड आरपी के तौर पर शामिल होने की प्रोसेस जारी है
आपको हर एंड आरपी के लिए, ये काम करने होंगे:
- Google को सूचना दें: नए आरपी और उसके इस्तेमाल के बारे में Google को सूचना देने के लिए, सर्टिफ़िकेट जारी करने वाले रजिस्ट्रार के क्लाइंट के तौर पर शामिल होने का फ़ॉर्म भरें.
- मेटाडेटा कॉन्फ़िगर करें: आरपी की डिसप्ले जानकारी (नाम, लोगो, निजता नीति का यूआरएल) भरें. साथ ही, उनके सर्टिफ़िकेट में ग्लोबल स्तर पर यूनीक डिसप्ले नेम (विषय) सेट करें.
तकनीकी जानकारी
A. सर्टिफ़िकेट प्रोफ़ाइल
अनुरोधों पर, स्टैंडर्ड X.509 v3 सर्टिफ़िकेट से हस्ताक्षर किए जाने चाहिए. ये सर्टिफ़िकेट, P-256 / ECDSA का इस्तेमाल करके जनरेट किए जाते हैं. साथ ही, इनमें Google का कस्टम एक्सटेंशन शामिल होता है:
- कस्टम एक्सटेंशन ओआईडी:
1.3.6.1.4.1.11129.10.1 - गंभीरता: सामान्य.
- कॉन्टेंट: यह
RelyingPartyMetadataBytesका SHA256 हैश होता है. इसे ASN.1OCTET STRINGमें एन्कोड किया जाता है.
B. मेटाडेटा स्कीमा (CBOR)
मेटाडेटा को 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 को Google Wallet के ब्रैंड से जुड़े दिशा-निर्देशों का पालन करना होगा.
C. OpenID4VP इंटिग्रेशन
हस्ताक्षर किए गए OpenID4VP क्रेडेंशियल के अनुरोध को फ़ॉर्मैट करते समय, client_metadata ऑब्जेक्ट में मौजूद gw_rp_metadata_bytes फ़ील्ड में, base64url के ज़रिए एन्कोड किया गया मेटाडेटा शामिल करें. जैसा कि यहां दिए गए सैंपल अनुरोध कोड में दिखाया गया है.
अनुपालन और सहमति वापस लेना
- गलत इस्तेमाल पर नज़र रखना: Google, आरपी के गलत इस्तेमाल पर नज़र रखता है. अगर उसे किसी तरह के गलत इस्तेमाल का पता चलता है, तो वह आपको इसकी सूचना देगा.
- सर्टिफ़िकेट तुरंत रद्द करना: आपको गलत इस्तेमाल करने वाले आरपी के सर्टिफ़िकेट तुरंत रद्द करने होंगे. साथ ही, निरस्त किए गए सर्टिफ़िकेट की अपडेट की गई सूची (सीआरएल) पब्लिश करनी होगी.
- ऑडिट करना: Google, पहचान छिपाकर रखे गए लॉग को सेव करता है. इससे यह पक्का किया जाता है कि आरपी के अनुरोध, इस्तेमाल के लिए रजिस्टर किए गए मामलों से मेल खाते हों.
अगले चरण
पुष्टि करने वाले रजिस्ट्रार के तौर पर शामिल होने के लिए, पुष्टि करने वाले रजिस्ट्रार के तौर पर शामिल होने का फ़ॉर्म भरें और सबमिट करें. बाद में शामिल होने वाले डाउनस्ट्रीम क्लाइंट को शामिल करने के लिए, Verifier Registrar Client Onboarding Form का इस्तेमाल करें.
ऑनबोर्डिंग और इंटिग्रेशन के बारे में अक्सर पूछे जाने वाले सवालों के लिए, डिजिटल आइडेंटिटी और क्रेडेंशियल के बारे में अक्सर पूछे जाने वाले सवाल देखें.
पुष्टि करने वाले रजिस्ट्रार के इंटिग्रेशन की जानकारी
इस सेक्शन में, Digital Credentials API के साथ इंटिग्रेट करने वाले Verifier Registrar के लिए, तकनीकी इंटिग्रेशन की जानकारी दी गई है. इसमें अनुरोध का फ़ॉर्मैट, अनुरोध को एन्क्रिप्ट (सुरक्षित) करना, एपीआई को ट्रिगर करना, जवाबों की पुष्टि करना, और ज़ीरो-नॉलेज प्रूफ़ लागू करना शामिल है.
इस्तेमाल किए जा सकने वाले फ़ॉर्मैट और सुविधाएँ
Google Wallet, आईएसओ एमडॉक पर आधारित डिजिटल आईडी के साथ काम करता है.
- इस्तेमाल किए जा सकने वाले क्रेडेंशियल: इस्तेमाल किए जा सकने वाले क्रेडेंशियल और एट्रिब्यूट देखे जा सकते हैं.
- इस्तेमाल किए जा सकने वाले प्रोटोकॉल: OpenID4VP (वर्शन 1.0).
- Android SDK का कम से कम वर्शन: Android 9 (एपीआई लेवल 28) और इसके बाद के वर्शन.
- ब्राउज़र के लिए सहायता: Digital Credentials API के साथ काम करने वाले ब्राउज़र की पूरी सूची देखने के लिए, इकोसिस्टम सहायता पेज पर जाएं.
- अक्सर पूछे जाने वाले सवाल: अगर आपको यह जानना है कि यह सुविधा किन देशों में उपलब्ध है और नए इलाकों में इसे कब लॉन्च किया जाएगा, तो क्रेडेंशियल और डेटा से जुड़े अक्सर पूछे जाने वाले सवाल देखें.
अनुरोध को फ़ॉर्मैट करना
किसी भी वॉलेट से क्रेडेंशियल का अनुरोध करने के लिए, आपको 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 में, हर अनुरोध के लिए एन्क्रिप्शन का सार्वजनिक पासकोड होता है.
आपको हर अनुरोध के लिए निजी कुंजियां सेव करनी होंगी. साथ ही, उनका इस्तेमाल Wallet ऐप्लिकेशन से मिले टोकन की पुष्टि करने और उसे अनुमति देने के लिए करना होगा.
इंटिग्रेट किया गया OpenID4VP मेटाडेटा
क्रेडेंशियल के लिए अनुरोध को फ़ॉर्मैट करते समय, आपको client_metadata ऑब्जेक्ट में gw_rp_metadata_bytes फ़ील्ड शामिल करना होगा. जैसा कि यहां दिए गए अनुरोध के सैंपल कोड में दिखाया गया है. इस फ़ील्ड में, Base64URL-encoded रिलाइंग पार्टी का मेटाडेटा होता है. Google Wallet को इसकी ज़रूरत होती है, ताकि वह आपकी पहचान की पुष्टि कर सके और उपयोगकर्ता को आपकी ब्रैंडिंग दिखा सके.
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
]
}
},
"gw_rp_metadata_bytes": "<base64url encoded metadata string>"
}
}
ज़रूरी शर्तें पूरी करने वाला कोई भी क्रेडेंशियल
यहां mDL और आईडी पास, दोनों के लिए अनुरोध का उदाहरण दिया गया है. उपयोगकर्ता इनमें से किसी एक तरीके का इस्तेमाल करके आगे बढ़ सकता है.
{
"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>"
}
}
Google Wallet में सेव किए गए किसी भी पहचान पत्र से, इस्तेमाल किए जा सकने वाले किसी भी एट्रिब्यूट के लिए अनुरोध किया जा सकता है.
हस्ताक्षर किए गए अनुरोध
साइन किए गए अनुरोध (JWT की मदद से सुरक्षित किए गए अनुमति के अनुरोध) में, पुष्टि किए जा सकने वाले प्रज़ेंटेशन के अनुरोध को क्रिप्टोग्राफ़िक तरीके से साइन किए गए JSON Web Token (JWT) में शामिल किया जाता है. इसके लिए, आपके पीकेआई इन्फ़्रास्ट्रक्चर का इस्तेमाल किया जाता है. इससे अनुरोध की अखंडता बनी रहती है और Google Wallet को आपकी पहचान की पुष्टि करने में मदद मिलती है.
ज़रूरी शर्तें
हस्ताक्षर किए गए अनुरोध के लिए कोड में बदलाव लागू करने से पहले, पक्का करें कि आपके पास ये चीज़ें हों:
- निजी कुंजी: अनुरोध पर हस्ताक्षर करने के लिए, आपको निजी कुंजी (जैसे, इलिप्टिक कर्व
ES256) की ज़रूरत होती है. इसे आपके सर्वर में मैनेज किया जाता है. - सर्टिफ़िकेट: आपको अपने पासकोड पेयर से मिला एक स्टैंडर्ड X.509 सर्टिफ़िकेट चाहिए.
- रजिस्ट्रेशन: पक्का करें कि आपका सार्वजनिक सर्टिफ़िकेट, Google Wallet में रजिस्टर हो.
अनुरोध निर्माण लॉजिक
अनुरोध बनाने के लिए, आपको अपने निजी पासकोड का इस्तेमाल करना होगा. साथ ही, पेलोड को 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
एपीआई को ट्रिगर करना
पूरा एपीआई अनुरोध, सर्वर साइड से जनरेट किया जाना चाहिए. प्लैटफ़ॉर्म के हिसाब से, जनरेट किए गए 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")
}
क्रेडेंशियल मैनेजर को कॉन्फ़िगर करना
CredentialManager ऑब्जेक्ट को कॉन्फ़िगर और शुरू करने के लिए, यहां दिए गए लॉजिक जैसा लॉजिक जोड़ें:
// Use your app or activity context to instantiate a client instance of CredentialManager.
val credentialManager = CredentialManager.create(context)
पहचान बताने वाले एट्रिब्यूट के लिए अनुरोध करना
पहचान से जुड़े अनुरोधों के लिए अलग-अलग पैरामीटर तय करने के बजाय, ऐप्लिकेशन उन सभी को CredentialOption में JSON स्ट्रिंग के तौर पर एक साथ उपलब्ध कराता है.
क्रेडेंशियल मैनेजर, इस JSON स्ट्रिंग को उपलब्ध डिजिटल वॉलेट को भेजता है. हालांकि, वह इसके कॉन्टेंट की जांच नहीं करता. इसके बाद, हर वॉलेट की यह ज़िम्मेदारी होती है:
- पहचान के अनुरोध को समझने के लिए, JSON स्ट्रिंग को पार्स करना.
- यह तय करना कि सेव किए गए क्रेडेंशियल में से कौनसे क्रेडेंशियल, अनुरोध को पूरा करते हैं.
हमारा सुझाव है कि पार्टनर, Android ऐप्लिकेशन इंटिग्रेशन के लिए भी सर्वर पर अनुरोध बनाएं.
GetDigitalCredentialOption() फ़ंक्शन कॉल में, अनुरोध फ़ॉर्मैट के requestJson का इस्तेमाल request के तौर पर किया जाएगा.
// 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 रिस्पॉन्स में, एन्क्रिप्ट (सुरक्षित) किया गया identityToken (JWT) शामिल होता है. इसे W3C ने तय किया है. इस जवाब को जनरेट करने की ज़िम्मेदारी 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 में भेजे गए सार्वजनिक पासकोड से जुड़े निजी पासकोड का इस्तेमाल करके, JWE को डिक्रिप्ट करें. इससे 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.
}
}
सेशन की ट्रांसक्रिप्ट बनाना
अगला चरण, ISO/IEC 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का इस्तेमाल करके, डिवाइस के जवाब की पुष्टि ISO/IEC 18013-5:2021 के क्लॉज़ 9 के मुताबिक की जानी चाहिए.पुष्टि करने की इस प्रोसेस में कई चरण शामिल हैं:
जारी करने वाले के सर्टिफ़िकेट की जांच करें:
issuerAuthसे, जारी करने वाले के साइनिंग सर्टिफ़िकेट की चेन निकालें. इसके बाद, भरोसेमंद IACA रूट सर्टिफ़िकेट के हिसाब से इसकी पुष्टि करें. इस तरह की सेवा देने वाले बैंक/वित्तीय संस्थान के IACA सर्टिफ़िकेट देखें.एमएसओ के हस्ताक्षर की पुष्टि करना (18013-5 सेक्शन 9.1.2)
डेटा एलिमेंट के लिए
ValueDigestsकी गिनती करना और उसकी जांच करना (18013-5 सेक्शन 9.1.2)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 कॉन्फ़िगरेशन दें.
ज़ेडकेपी क्या है और इसकी क्षमताओं के बारे में खास जानकारी पाने के लिए, अक्सर पूछे जाने वाले सवाल देखें.
...
"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 लाइब्रेरी का इस्तेमाल करके, इस सबूत की पुष्टि IACA सर्टिफ़िकेट जारी करने वालों के ख़िलाफ़ की जा सकती है.
verifier-service में, डिप्लॉयमेंट के लिए तैयार, Docker पर आधारित सर्वर होता है. इससे, कुछ जारीकर्ता IACA सर्टिफ़िकेट के ख़िलाफ़ जवाब की पुष्टि की जा सकती है.
आपको जिन IACA जारी करने वाले सर्टिफ़िकेट पर भरोसा करना है उन्हें मैनेज करने के लिए, certs.pem में बदलाव किया जा सकता है.
संसाधन और सहायता
- अक्सर पूछे जाने वाले सवाल: तकनीकी इंटिग्रेशन के बारे में अक्सर पूछे जाने वाले सवालों के लिए, डिजिटल आइडेंटिटी और क्रेडेंशियल के बारे में अक्सर पूछे जाने वाले सवाल देखें.
- रेफ़रंस इंप्लीमेंटेशन: GitHub पर, पहचान की पुष्टि करने वालों के लिए रेफ़रंस इंप्लीमेंटेशन देखें.
- टेस्ट वेबसाइट: verifier.multipaz.org पर जाकर, शुरू से लेकर आखिर तक के फ़्लो को आज़माएं.
- OpenID4VP की खास जानकारी: openID4VP की तकनीकी जानकारी देखें.
- सहायता: इंटिग्रेशन के दौरान डीबग करने से जुड़ी सहायता पाने या कोई सवाल पूछने के लिए,
wallet-identity-rp-support@google.comसे संपर्क करें.