इस गाइड में बताया गया है कि भरोसा करने वाली इकाइयां (आरपी) और रीडर डेवलपर, Google Wallet में मौजूद डिजिटल क्रेडेंशियल की पुष्टि व्यक्तिगत तौर पर (ऑफ़लाइन) कैसे कर सकते हैं. यह पुष्टि, अंतरराष्ट्रीय ISO/IEC 18013-5 स्टैंडर्ड के मुताबिक की जाती है.
Google Wallet में मौजूद डिजिटल क्रेडेंशियल को फ़िज़िकल जगहों पर सुरक्षित तरीके से वेरिफ़ाई किया जा सकता है. जैसे, पॉइंट ऑफ़ सेल टर्मिनल, इवेंट की जगहें, बस या मेट्रो के गेट, कानून लागू करने वाली संस्थाओं के रीडर, और मोबाइल रीडर ऐप्लिकेशन. इसके लिए, क्रेडेंशियल दिखाते समय इंटरनेट कनेक्शन की ज़रूरत नहीं होती.
ऑफ़लाइन प्रज़ेंटेशन (ISO/IEC 18013-5) की खास जानकारी
ISO/IEC 18013-5 स्टैंडर्ड, होल्डर (Google Wallet चलाने वाला उपयोगकर्ता का मोबाइल डिवाइस) और रीडर / पुष्टि करने वाले (फ़िज़िकल टर्मिनल या साथी मोबाइल ऐप्लिकेशन) के बीच ऑफ़लाइन प्रज़ेंटेशन के लिए, स्टैंडर्ड और इंटरऑपरेबल प्रोटोकॉल तय करता है.
प्रज़ेंटेशन का फ़्लो अलग-अलग चरणों में होता है:
- डिवाइस का जुड़ाव: रीडर और Wallet, एनएफ़सी टैप (स्टैटिक या नेगोशिएटेड हैंडओवर) या क्यूआर कोड स्कैन के ज़रिए शुरुआती संपर्क स्थापित करते हैं. इस चरण के दौरान, डिवाइस के यूज़र ऐक्टिविटी मेटाडेटा और रीडर के कुछ समय के लिए इस्तेमाल होने वाले सार्वजनिक पासकोड (
EReaderKey) को शेयर किया जाता है. - डेटा ट्रांसफ़र कनेक्शन: एन्क्रिप्ट (सुरक्षित) किया गया एक सुरक्षित ब्लूटूथ लो एनर्जी (बीएलई) चैनल तय किया जाता है. इसमें रीडर, सेंट्रल क्लाइंट या पेरिफ़ेरल सर्वर मोड में काम करता है.
- डिवाइस से अनुरोध: रीडर, CBOR-कोड में बदले गए
DeviceRequestको ट्रांसमिट करता है. इसमें अनुरोध किए गए दस्तावेज़ के टाइप (जैसे,org.iso.18013.5.1.mDL) के साथ-साथ, अनुरोध किए गए खास नेमस्पेस और डेटा एलिमेंट की जानकारी होती है. - उपयोगकर्ता की सहमति और डिवाइस की पुष्टि: Google Wallet, उपयोगकर्ता से अनुरोध किए गए डेटा एलिमेंट की समीक्षा करने और बायोमेट्रिक ऑथेंटिकेशन या स्क्रीन लॉक का इस्तेमाल करके, डेटा शेयर करने की पुष्टि करने के लिए कहता है.
- डिवाइस से मिला जवाब और क्रिप्टोग्राफ़िक तरीके से पुष्टि: वॉलेट, CBOR-एन्कोड किया गया
DeviceResponseवापस भेजता है. इसमें साइन किया गया मोबाइल सिक्योरिटी ऑब्जेक्ट (एमएसओ) और डिवाइस से साइन किया गया डेटा एलिमेंट शामिल होता है. रीडर, भरोसेमंद रूट सर्टिफ़िकेट के आधार पर क्रिप्टोग्राफ़िक सिग्नेचर की पुष्टि करता है.
Multipaz ओपन-सोर्स एसडीके
रीडर या पुष्टि करने वाला ऐप्लिकेशन लागू करने के लिए, Google Multipaz का इस्तेमाल करने का सुझाव देता है. यह एक ओपन-सोर्स Kotlin Multiplatform (KMP) SDK टूल है. इसे Google ने डेवलप किया है और OpenWallet Foundation (OWF) में शामिल किया है.
Multipaz, ISO/IEC 18013-5 रीडर और वॉलेट प्रोटोकॉल, क्रिप्टोग्राफ़िक तरीके से पुष्टि करने वाली पाइपलाइन, CBOR एन्कोडिंग/डिकोडिंग, और एक्सटेंसिबल दस्तावेज़ टाइप स्कीमा को लागू करने की सुविधा देता है.
अपने रीडर ऐप्लिकेशन में Multipaz को इंटिग्रेट करना
यहां दिए गए तरीके से, Multipaz SDK को Android रीडर ऐप्लिकेशन में इंटिग्रेट करने का तरीका बताया गया है.
पहला चरण: डिपेंडेंसी जोड़ना
Multipaz लाइब्रेरी, Maven Central पर पब्लिश की जाती हैं. अपने ऐप्लिकेशन की build.gradle.kts फ़ाइल में ज़रूरी मॉड्यूल जोड़ें:
// build.gradle.kts
dependencies {
// Core Multipaz library (protocol engine, CBOR, crypto)
implementation("org.multipaz:multipaz:0.100.0")
// Android-specific platform bindings (NFC, BLE, Keystore)
implementation("org.multipaz:multipaz-android:0.100.0")
// Standardized document types (mDL, EU PID, etc.)
implementation("org.multipaz:multipaz-doctypes:0.100.0")
}
दूसरा चरण: Android की अनुमतियां कॉन्फ़िगर करना
व्यक्तिगत तौर पर पुष्टि करने के लिए, हार्डवेयर की अनुमतियां ज़रूरी हैं. जैसे, एनएफ़सी का इस्तेमाल करने, कैमरे से स्कैन करने (क्यूआर कोड का इस्तेमाल करने के लिए), और ब्लूटूथ लो एनर्जी की मदद से डेटा ट्रांसफ़र करने की अनुमति. अपनी AndroidManifest.xml में ये अनुमतियां जोड़ें:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- NFC Engagement -->
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<!-- Camera for QR Code Engagement -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<!-- Bluetooth Low Energy Transport (Android 12+) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Legacy Bluetooth Permissions for Android 11 and lower -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
</manifest>
तीसरा चरण: पुष्टि करने वाले इंजन को शुरू करना
Multipaz के VerificationHelper या Reader कनेक्शन एब्स्ट्रैक्शन का इस्तेमाल करके, यूज़र ऐक्टिविटी इवेंट मैनेज करें और बीएलई कम्यूनिकेशन लाइफ़साइकल को मैनेज करें:
import org.multipaz.verification.VerificationHelper
import org.multipaz.cbor.Cbor
import org.multipaz.crypto.Crypto
class ReaderManager(private val context: android.content.Context) {
private var verificationHelper: VerificationHelper? = null
fun startListeningForEngagement() {
verificationHelper = VerificationHelper.Builder(
context = context,
listener = object : VerificationHelper.Listener {
override fun onDeviceConnected() {
// BLE channel established, send request
sendDeviceRequest()
}
override fun onResponseReceived(deviceResponseBytes: ByteArray) {
// Process and verify the received credential payload
handleDeviceResponse(deviceResponseBytes)
}
override fun onError(error: Throwable) {
// Handle transport or protocol errors
}
override fun onDeviceDisconnected(transportTransportSpecificTermination: Boolean) {
// Connection closed
}
}
).build()
}
}
चौथा चरण: DeviceRequest बनाना
दस्तावेज़ का टाइप और वह डेटा एलिमेंट बताएं जिसकी पुष्टि आपके ऐप्लिकेशन को करनी है. हमेशा कम से कम जानकारी ज़ाहिर करने के सिद्धांत को लागू करें. उदाहरण के लिए, उम्र की पुष्टि करते समय, पूरी birth_date के बजाय सिर्फ़ age_over_21 का अनुरोध करें:
fun sendDeviceRequest() {
// Specify the DocType and requested elements
val docType = "org.iso.18013.5.1.mDL"
val namespace = "org.iso.18013.5.1"
// Map of requested elements: elementName -> intentToRetain
val requestedElements = mapOf(
"family_name" to false,
"given_name" to false,
"age_over_21" to false,
"portrait" to false,
"driving_privileges" to false
)
// Build ISO/IEC 18013-5 DeviceRequest structure
val deviceRequestBytes = verificationHelper?.buildDeviceRequest(
docType = docType,
itemsToRequest = mapOf(namespace to requestedElements)
)
if (deviceRequestBytes != null) {
verificationHelper?.sendDeviceRequest(deviceRequestBytes)
}
}
अन्य तरह के दस्तावेज़ों (DocTypes) के साथ काम करना
Multipaz, स्टैंडर्ड क्रेडेंशियल के साथ काम करता है. साथ ही, यह एक ऐसा आर्किटेक्चर उपलब्ध कराता है जिसे ज़रूरत के हिसाब से बढ़ाया जा सकता है. इससे, कस्टम या डोमेन के हिसाब से दस्तावेज़ के टाइप का अनुरोध किया जा सकता है.
1. पहले से मौजूद स्टैंडर्ड दस्तावेज़ टाइप
multipaz-doctypes लाइब्रेरी, स्टैंडर्ड क्रेडेंशियल के लिए पहले से तय किए गए स्कीमा मॉडल उपलब्ध कराती है:
| दस्तावेज़ के टाइप का आइडेंटिफ़ायर | स्टैंडर्ड / दायरा | सामान्य नेमस्पेस | सामान्य एलिमेंट |
|---|---|---|---|
org.iso.18013.5.1.mDL |
ISO/IEC 18013-5 मोबाइल ड्राइविंग लाइसेंस | org.iso.18013.5.1 |
family_name, given_name, birth_date, issue_date, expiry_date, issuing_authority, document_number, portrait, driving_privileges, age_over_18, age_over_21 |
eu.europa.ec.eudi.pid.1 |
ईयू डिजिटल आइडेंटिटी वॉलेट (ईयूडीडब्ल्यू) में मौजूद, व्यक्ति की पहचान से जुड़ा डेटा | eu.europa.ec.eudi.pid.1 |
family_name, first_name, birth_date, nationality, issuing_country, issuing_authority, personal_administrative_number |
com.google.wallet.idcard.1 |
Google Wallet में मौजूद आईडी पास / टेस्ट आईडी | com.google.wallet.idcard.1 |
given_name, family_name, birth_date, document_number, portrait |
2. कस्टम दस्तावेज़ टाइप का अनुरोध करना
कस्टम दस्तावेज़ टाइप का अनुरोध करने के लिए, DeviceRequest बनाते समय टारगेट docType स्ट्रिंग और उससे जुड़ी नेमस्पेस मैपिंग तय करें:
// Example: Requesting a custom event ticket credential
val customDocType = "com.example.events.ticket"
val customNamespace = "com.example.events.ticket.1"
val customRequestedItems = mapOf(
"ticket_id" to false,
"event_name" to false,
"seat_section" to false,
"vip_access" to false
)
val multiDocRequestBytes = verificationHelper?.buildMultiDocDeviceRequest(
documents = listOf(
DocumentRequest(
docType = customDocType,
namespaces = mapOf(customNamespace to customRequestedItems)
)
)
)
क्रिप्टोग्राफ़िक वेरिफिकेशन और ट्रस्ट मैनेजमेंट
रिस्पॉन्स पेलोड पाना सिर्फ़ पहला चरण है. रीडर को चार चरणों वाली क्रिप्टोग्राफ़िक पुष्टि की प्रक्रिया ज़रूर पूरी करनी होगी. इससे, पेश किए गए क्रेडेंशियल की प्रामाणिकता और इंटिग्रिटी की पुष्टि की जा सकेगी.
| पुष्टि करने का चरण | पुष्टि करने का टारगेट |
|---|---|
| 1. आईडी जारी करने वाले की तरफ़ से पुष्टि | आईएसीए के भरोसेमंद रूट सर्टिफ़िकेट की मदद से, IssuerAuth (COSE_Sign1) की पुष्टि करना |
| 2. समयसीमा की जांच | पक्का करें कि validFrom ≤ मौजूदा समय ≤ validUntil |
| 3. डेटा के रखरखाव की जांच | वापस मिले एलिमेंट के SHA-256 डाइजेस्ट की गणना करें और MSO ValueDigests से मैच करें |
| 4. डिवाइस की पुष्टि करना | SessionTranscript से जुड़े DeviceKey का इस्तेमाल करके, DeviceSigned के हस्ताक्षर या एमएसी की पुष्टि करें |
1. पुष्टि करने की चार चरणों वाली प्रोसेस
- कार्ड जारी करने वाले बैंक से पुष्टि (
IssuerAuth):- मोबाइल सिक्योरिटी ऑब्जेक्ट (एमएसओ) पर, आईडी जारी करने वाली संस्था (
IssuerAuthपेलोड) के हस्ताक्षर होते हैं. - रीडर, दस्तावेज़ पर हस्ताक्षर करने वाले के सर्टिफ़िकेट का इस्तेमाल करके,
COSE_Sign1हस्ताक्षर की पुष्टि करता है. साथ ही, यह पक्का करता है कि सर्टिफ़िकेट, सर्टिफ़िकेट जारी करने वाली संस्था (आईएसीए) के भरोसेमंद रूट सर्टिफ़िकेट से जुड़ा हो.
- मोबाइल सिक्योरिटी ऑब्जेक्ट (एमएसओ) पर, आईडी जारी करने वाली संस्था (
- मान्यता की अवधि की पुष्टि करना:
- रीडर, MSO में मौजूद
validityInfo.validFromऔरvalidityInfo.validUntilटाइमस्टैंप की तुलना अपनी मौजूदा घड़ी से करता है. इससे यह पक्का किया जाता है कि क्रेडेंशियल की समयसीमा खत्म न हुई हो.
- रीडर, MSO में मौजूद
- डेटा के रखरखाव की पुष्टि (
ValueDigests):- हर
IssuerSignedItemके लिए, रीडर उसके डाइजेस्ट (जैसे, SHA-256) का हिसाब लगाता है. साथ ही, यह पुष्टि करता है कि वह MSO कीValueDigestsडिक्शनरी में मौजूद हैश एंट्री से मेल खाता है या नहीं.
- हर
- डिवाइस की पुष्टि करना (
DeviceSigned):- रीडर यह पुष्टि करता है कि क्रेडेंशियल दिखाने वाले डिवाइस के पास, साइन किए गए MSO में पब्लिश किए गए
DeviceKeyसे जुड़ी निजी कुंजी है. - इसके लिए,
SessionTranscriptपरDeviceAuth(DeviceSignatureयाDeviceMac) की पुष्टि की जाती है. साथ ही, सेशन को रीडर की कुछ समय के लिए इस्तेमाल होने वाली कुंजी से बाइंड किया जाता है. इससे, रीप्ले और मैन-इन-द-मिडल अटैक को रोका जा सकता है.
- रीडर यह पुष्टि करता है कि क्रेडेंशियल दिखाने वाले डिवाइस के पास, साइन किए गए MSO में पब्लिश किए गए
2. भरोसेमंद आईएसीए रूट सर्टिफ़िकेट मैनेज करना
प्रोडक्शन रीडर को एक सुरक्षित और स्थानीय ट्रस्ट स्टोर बनाए रखना चाहिए. इसमें भरोसेमंद आईएसीए रूट सर्टिफ़िकेट शामिल होने चाहिए:
- Production IACA Certificates: आधिकारिक तौर पर सर्टिफ़िकेट जारी करने वाली संस्थाओं से रूट सर्टिफ़िकेट डाउनलोड और कॉन्फ़िगर करें. सर्टिफ़िकेट जारी करने वाली ऐसी संस्थाएं और आईएसीए सर्टिफ़िकेट की सूची देखें जो Google के साथ काम करती हैं.
- AAMVA VICAL: अमेरिका के अधिकार क्षेत्रों के लिए, रीडर सिस्टम को अमेरिकन असोसिएशन ऑफ़ मोटर वीइकल एडमिनिस्ट्रेटर (AAMVA) की वेरिफ़ाइड जारीकर्ता सर्टिफ़िकेट अथॉरिटी लिस्ट (VICAL) सेवा के साथ इंटिग्रेट किया जा सकता है. इससे, राज्य के ट्रस्ट ऐंकर अपने-आप सिंक हो जाते हैं.
- सैंडबॉक्स टेस्टिंग रूट: सैंडबॉक्स क्रेडेंशियल के साथ टेस्ट करते समय, पक्का करें कि रीडर, Google Sandbox IACA रूट पर भरोसा करता हो.
import org.multipaz.crypto.X509Cert
// Configure trusted IACA certificates in the trust store
val trustedCertificates = mutableListOf<X509Cert>()
// Add official state IACA certificates
trustedCertificates.add(X509Cert.fromPem(sampleStateIacaPem))
// Add Google Sandbox IACA root certificate for testing
trustedCertificates.add(X509Cert.fromPem(googleSandboxIacaPem))
val verifier = MultipazVerifier(trustStore = trustedCertificates)
val verificationResult = verifier.verify(deviceResponseBytes, sessionTranscript)
if (verificationResult.isIssuerAuthorized && verificationResult.isDeviceAuthenticated) {
// Credential is valid and authentic
} else {
// Reject presentation: cryptographic validation failed
}
रीडर की पुष्टि (सुझाया गया)
रीडर ऑथेंटिकेशन की मदद से, रीडर ऐप्लिकेशन, Google Wallet को क्रिप्टोग्राफ़ी के ज़रिए अपनी पहचान की पुष्टि कर सकता है. इसके लिए, उसे अनुमति वाले X.509 रीडर सर्टिफ़िकेट का इस्तेमाल करके, ReaderAuthentication स्ट्रक्चर पर हस्ताक्षर करना होगा.
- इसका सुझाव क्यों दिया जाता है: रीडर ऑथेंटिकेशन की मदद से, आपका रीडर ऐप्लिकेशन या टर्मिनल, उपयोगकर्ता को भरोसेमंद पहचान दिखा सकता है. सार्वजनिक तौर पर उपलब्ध बुनियादी एट्रिब्यूट (जैसे,
age_over_21की पुष्टि करना) के लिए, यह ज़रूरी नहीं है.हालांकि, उपयोगकर्ताओं का भरोसा बढ़ाने के लिए, रीडर इंटिग्रेशन के लिए इसका सुझाव दिया जाता है. संवेदनशील एट्रिब्यूट (जैसे, पूरा सोशल सिक्योरिटी नंबर, घर का पता या राज्य से जुड़े खास एंडॉर्समेंट) का अनुरोध करते समय, कानूनी तौर पर या नीति के तहत इसकी ज़रूरत पड़ सकती है. - यह कैसे काम करता है: रीडर, अपने सर्टिफ़िकेट की चेन को शामिल करता है और सेशन ट्रांसक्रिप्ट पर हस्ताक्षर करता है. डेटा शेयर करने से पहले, Google Wallet उपयोगकर्ता को ऐसी स्क्रीन जहां OAuth के लिए सहमति दी जाती है पर, रीडर की पुष्टि की गई पहचान और संगठन का नाम दिखाता है.
टेस्टिंग और डेवलपमेंट टूल
इंटिग्रेशन की प्रोसेस को तेज़ करने के लिए, इन डेवलपर टूल और रेफ़रंस इंप्लिमेंटेशन का इस्तेमाल करें:
- Multipaz Reference Apps:
- Multipaz रिपॉज़िटरी को क्लोन करें और
IdentityReaderAndroid सैंपल के तौर पर मिला ऐप्लिकेशन चलाएं, ताकि पहचान की पुष्टि करने के फ़्लो को टेस्ट किया जा सके.
- Multipaz रिपॉज़िटरी को क्लोन करें और
- Google Wallet में टेस्ट आईडी बनाना:
- Utopia ePassport Simulator का इस्तेमाल करके, Google Wallet में सिम्युलेट किए गए टेस्ट क्रेडेंशियल को जोड़ने के लिए, Google Wallet में टेस्ट आईडी पास बनाना गाइड में दिया गया तरीका अपनाएं.
- वेब पर आधारित वेरिफ़ायर टेस्टिंग:
- CBOR अनुरोधों की जांच करने, दावे से जुड़ी क्वेरी एक्सप्लोर करने, और W3C / आईएसओ 18013-7 वेब पर आधारित प्रज़ेंटेशन की जांच करने के लिए, verifier.multipaz.org का इस्तेमाल करें.
समस्या हल करना और फ़ील्ड डाइग्नोस्टिक्स
यहां दी गई टेबल में, ऑफ़लाइन पुष्टि के दौरान होने वाली आम समस्याएं और उन्हें हल करने के लिए सुझाए गए तरीके दिए गए हैं:
| समस्या / गड़बड़ी का ब्यौरा | असल वजह | सुझाया गया रिज़ॉल्यूशन |
|---|---|---|
| BLE कनेक्शन टाइम आउट / कनेक्ट न हो पाना |
|
|
| एनएफ़सी टैप की सुविधा काम नहीं कर रही है या बंद हो गई है | उपयोगकर्ता ने बीएलई हैंडओवर रिकॉर्ड पूरी तरह से ट्रांसफ़र होने से पहले ही, मोबाइल डिवाइस को रीडर ऐंटीना से दूर कर दिया. |
|
UNTRUSTED_ISSUER / सर्टिफ़िकेट चेन से जुड़ी गड़बड़ी |
रीडर के लोकल ट्रस्ट स्टोर में मौजूद किसी भी भरोसेमंद आईएसीए सर्टिफ़िकेट से, दस्तावेज़ पर हस्ताक्षर करने वाले का सर्टिफ़िकेट लिंक नहीं है. |
|
INVALID_VALIDITY_INFO / Expired MSO |
|
|
DEVICE_AUTHENTICATION_FAILED |
रीडर और Wallet के बीच सेशन ट्रांसक्रिप्ट मेल नहीं खाती या कुछ समय के लिए इस्तेमाल होने वाले डिवाइस का हस्ताक्षर अमान्य है. |
|
| Android 12 और इसके बाद के वर्शन पर, अनुमति से जुड़ी गड़बड़ी की वजह से ऐप्लिकेशन क्रैश होना | ऐप्लिकेशन ने रनटाइम की अनुमतियों के बिना, बीएलई पर स्कैन करने या विज्ञापन दिखाने की कोशिश की. |
|
इन-पर्सन रीडर के लिए यूएक्स और निजता से जुड़े दिशा-निर्देश
फ़िज़िकल रीडर और कंपैनियन ऐप्लिकेशन डिज़ाइन करते समय:
- यूज़र इंटरफ़ेस (यूआई) में चुनिंदा जानकारी ज़ाहिर करें: ऑपरेटर को सिर्फ़ फ़ैसले या ज़रूरी एट्रिब्यूट दिखाएं. उदाहरण के लिए, उपयोगकर्ता की जन्म की तारीख, पता, और लाइसेंस नंबर दिखाने के बजाय, हरे रंग का सही का निशान और "21 साल से ज़्यादा उम्र की पुष्टि हो गई है" दिखाएं.
- फ़िज़िकल इंटरैक्शन के इंडिकेटर साफ़ तौर पर दिखाएं: एनएफ़सी टारगेट ज़ोन को साफ़ तौर पर लेबल करें. साथ ही, हर चरण को दिखाने वाले विज़ुअल क्यू (जैसे, ऐनिमेशन या प्रोग्रेस बार) दिखाएं: टैप / स्कैन करें → कनेक्ट किया जा रहा है → पुष्टि की जा रही है → पूरा हुआ.
- कुछ समय के लिए डेटा मैनेज करना: Wallet से मिले निजी डेटा एलिमेंट को सेव या लॉग न करें. हालांकि, अगर लागू कानून के तहत ऐसा करना ज़रूरी है और
intentToRetain = trueके ज़रिए इसकी जानकारी दी गई है, तो ऐसा किया जा सकता है.