ক্রেডেনশিয়াল ম্যানেজার হোল্ডার এপিআই আপনার অ্যান্ড্রয়েড হোল্ডার (যাকে "ওয়ালেট"ও বলা হয়) অ্যাপটিকে যাচাইকারীদের কাছে ডিজিটাল ক্রেডেনশিয়াল পরিচালনা এবং উপস্থাপন করতে সক্ষম করে।
মূল ধারণা
হোল্ডার এপিআই ব্যবহার করার আগে নিম্নলিখিত ধারণাগুলির সাথে নিজেকে পরিচিত করা গুরুত্বপূর্ণ।
শংসাপত্রের ফর্ম্যাট
হোল্ডার অ্যাপগুলিতে বিভিন্ন ক্রেডেনশিয়াল ফর্ম্যাটে শংসাপত্র সংরক্ষণ করা যেতে পারে। এই ফর্ম্যাটগুলি একটি ক্রেডেনশিয়াল কীভাবে উপস্থাপন করা উচিত তার জন্য নির্দিষ্টকরণ, এবং প্রতিটিতে ক্রেডেনশিয়াল সম্পর্কে নিম্নলিখিত তথ্য থাকে:
- ধরণ: বিশ্ববিদ্যালয়ের ডিগ্রি বা মোবাইল ড্রাইভিং লাইসেন্সের মতো বিভাগ।
- বৈশিষ্ট্য: প্রথম এবং শেষ নাম ইত্যাদি বৈশিষ্ট্য।
- এনকোডিং: শংসাপত্রটি যেভাবে গঠন করা হয়, উদাহরণস্বরূপ SD-JWT বা mdoc
- বৈধতা: ক্রিপ্টোগ্রাফিকভাবে শংসাপত্রের সত্যতা যাচাই করার পদ্ধতি।
প্রতিটি শংসাপত্রের বিন্যাস এনকোডিং এবং বৈধতা সামান্য ভিন্নভাবে করে, কিন্তু কার্যকরীভাবে তারা একই।
রেজিস্ট্রি দুটি ফর্ম্যাট সমর্থন করে:
- SD-JWT: IETF SD-JWT-ভিত্তিক যাচাইযোগ্য শংসাপত্র (SD-JWT VC) স্পেসিফিকেশন মেনে চলে।
- মোবাইল ডকুমেন্টস বা mdocs: ISO/IEC 18013-5:2021 স্পেসিফিকেশন মেনে চলে।
ক্রেডেনশিয়াল ম্যানেজার ব্যবহার করার সময় একজন যাচাইকারী SD-JWT এবং mdocs-এর জন্য OpenID4VP অনুরোধ করতে পারেন। ব্যবহারের ক্ষেত্রে এবং শিল্পের পছন্দের উপর নির্ভর করে পছন্দটি পরিবর্তিত হয়।
ক্রেডেনশিয়াল মেটাডেটা নিবন্ধন
ক্রেডেনশিয়াল ম্যানেজার সরাসরি কোনও ধারকের ক্রেডেনশিয়াল সংরক্ষণ করে না, বরং ক্রেডেনশিয়ালগুলির মেটাডেটা সংরক্ষণ করে । একটি ধারক অ্যাপকে প্রথমে RegistryManager ব্যবহার করে ক্রেডেনশিয়াল ম্যানেজারের সাথে ক্রেডেনশিয়াল মেটাডেটা নিবন্ধন করতে হবে। এই নিবন্ধন প্রক্রিয়াটি একটি রেজিস্ট্রি রেকর্ড তৈরি করে যা দুটি মূল উদ্দেশ্যে কাজ করে:
- মিল: ভবিষ্যতের যাচাইকারী অনুরোধের সাথে মেলানোর জন্য নিবন্ধিত শংসাপত্রের মেটাডেটা ব্যবহার করা হয়।
- প্রদর্শন: কাস্টমাইজড UI উপাদানগুলি ব্যবহারকারীকে ক্রেডেনশিয়াল নির্বাচক ইন্টারফেসে দেখানো হয়।
আপনার ডিজিটাল শংসাপত্র নিবন্ধনের জন্য আপনাকে OpenId4VpRegistry ক্লাস ব্যবহার করতে হবে, কারণ এটি mdoc এবং SD-JWT শংসাপত্র উভয় ফর্ম্যাটকেই সমর্থন করে। যাচাইকারীরা এই শংসাপত্রগুলি অনুরোধ করার জন্য OpenID4VP অনুরোধ পাঠাবে।
আপনার অ্যাপের শংসাপত্র নিবন্ধন করুন
ক্রেডেনশিয়াল ম্যানেজার হোল্ডার API ব্যবহার করতে, আপনার অ্যাপ মডিউলের বিল্ড স্ক্রিপ্টে নিম্নলিখিত নির্ভরতা যোগ করুন:
গ্রোভি
dependencies { // Use to implement credentials registrys implementation "androidx.credentials.registry:registry-digitalcredentials-mdoc:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-digitalcredentials-preview:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-provider:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-provider-play-services:1.0.0-alpha04" }
কোটলিন
dependencies { // Use to implement credentials registrys implementation("androidx.credentials.registry:registry-digitalcredentials-mdoc:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-digitalcredentials-preview:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-provider:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-provider-play-services:1.0.0-alpha04") }
রেজিস্ট্রি ম্যানেজার তৈরি করুন
একটি RegistryManager ইনস্ট্যান্স তৈরি করুন এবং এটি দিয়ে একটি OpenId4VpRegistry অনুরোধ নিবন্ধন করুন।
// Create the registry manager
val registryManager = RegistryManager.create(context)
// The guide covers how to build this out later
val registryRequest = OpenId4VpRegistry(credentialEntries, id)
try {
registryManager.registerCredentials(registryRequest)
} catch (e: Exception) {
// Handle exceptions
}
একটি OpenId4VpRegistry অনুরোধ তৈরি করুন
আগেই উল্লেখ করা হয়েছে, একজন যাচাইকারীর কাছ থেকে OpenID4VP অনুরোধ পরিচালনা করার জন্য আপনাকে একটি OpenId4VpRegistry নিবন্ধন করতে হবে। আমরা ধরে নিচ্ছি যে আপনার ওয়ালেট শংসাপত্রের সাথে কিছু স্থানীয় ডেটা টাইপ লোড করা আছে (উদাহরণস্বরূপ, sdJwtsFromStorage )। আপনি এখন তাদের ফর্ম্যাটের উপর ভিত্তি করে আমাদের Jetpack DigitalCredentialEntry সমতুল্যগুলিতে রূপান্তর করবেন - যথাক্রমে SD-JWT বা mdoc এর জন্য SdJwtEntry বা MdocEntry ।
রেজিস্ট্রিতে Sd-JWT যোগ করুন
রেজিস্ট্রির জন্য প্রতিটি স্থানীয় SD-JWT শংসাপত্র একটি SdJwtEntry তে ম্যাপ করুন:
fun mapToSdJwtEntries(sdJwtsFromStorage: List<StoredSdJwtEntry>): List<SdJwtEntry> {
val list = mutableListOf<SdJwtEntry>()
for (sdJwt in sdJwtsFromStorage) {
list.add(
SdJwtEntry(
verifiableCredentialType = sdJwt.getVCT(),
claims = sdJwt.getClaimsList(),
entryDisplayPropertySet = sdJwt.toDisplayProperties(),
id = sdJwt.getId() // Make sure this cannot be readily guessed
)
)
}
return list
}
রেজিস্ট্রিতে mdocs যোগ করুন
আপনার স্থানীয় mdoc শংসাপত্রগুলিকে Jetpack টাইপ MdocEntry তে ম্যাপ করুন:
fun mapToMdocEntries(mdocsFromStorage: List<StoredMdocEntry>): List<MdocEntry> {
val list = mutableListOf<MdocEntry>()
for (mdoc in mdocsFromStorage) {
list.add(
MdocEntry(
docType = mdoc.retrieveDocType(),
fields = mdoc.getFields(),
entryDisplayPropertySet = mdoc.toDisplayProperties(),
id = mdoc.getId() // Make sure this cannot be readily guessed
)
)
}
return list
}
কোড সম্পর্কে গুরুত্বপূর্ণ বিষয়সমূহ
-
idফিল্ড কনফিগার করার একটি পদ্ধতি হল একটি এনক্রিপ্ট করা ক্রেডেনশিয়াল আইডেন্টিফায়ার নিবন্ধন করা, যাতে শুধুমাত্র আপনিই মানটি ডিক্রিপ্ট করতে পারেন। - উভয় ফর্ম্যাটের জন্য UI প্রদর্শন ক্ষেত্রগুলি স্থানীয়করণ করা উচিত।
আপনার শংসাপত্র নিবন্ধন করুন
আপনার রূপান্তরিত এন্ট্রিগুলি একত্রিত করুন এবং RegistryManager সাথে অনুরোধটি নিবন্ধন করুন:
val credentialEntries = mapToSdJwtEntries(sdJwtsFromStorage) + mapToMdocEntries(mdocsFromStorage)
val openidRegistryRequest = OpenId4VpRegistry(
credentialEntries = credentialEntries,
id = "my-wallet-openid-registry-v1" // A stable, unique ID to identify your registry record.
)
এখন, আমরা CredentialManager-এর সাথে আপনার শংসাপত্র নিবন্ধন করতে প্রস্তুত।
try {
val response = registryManager.registerCredentials(openidRegistryRequest)
} catch (e: Exception) {
// Handle failure
}
আপনি এখন ক্রেডেনশিয়াল ম্যানেজারের সাথে আপনার ক্রেডেনশিয়াল নিবন্ধিত করেছেন।
অ্যাপ মেটাডেটা ব্যবস্থাপনা
আপনার হোল্ডার অ্যাপটি CredentialManager-এ যে মেটাডেটা নিবন্ধন করে তাতে নিম্নলিখিত বৈশিষ্ট্য রয়েছে:
- স্থায়িত্ব: তথ্য স্থানীয়ভাবে সংরক্ষণ করা হয়, রিবুট জুড়ে স্থায়ী হয়।
- সাইলয়েড স্টোরেজ: প্রতিটি অ্যাপের রেজিস্ট্রি রেকর্ড আলাদাভাবে সংরক্ষণ করা হয়, যার অর্থ একটি অ্যাপ অন্য অ্যাপের রেজিস্ট্রি রেকর্ড পরিবর্তন করতে পারে না।
- কীড আপডেট: প্রতিটি অ্যাপের রেজিস্ট্রি রেকর্ড একটি
idদ্বারা কীড করা হয়, যা রেকর্ডগুলি পুনরায় সনাক্তকরণ, আপডেট করা বা মুছে ফেলার অনুমতি দেয়। - মেটাডেটা আপডেট করা: যখনই আপনার অ্যাপ পরিবর্তন হয় বা প্রথম লোড হয় তখনই স্থায়ী মেটাডেটা আপডেট করা ভালো অভ্যাস। যদি একই
idঅধীনে একাধিকবার একটি রেজিস্ট্রি কল করা হয়, তাহলে সর্বশেষ কলটি পূর্ববর্তী সমস্ত রেকর্ড ওভাররাইট করে। আপডেট করার জন্য, প্রথমে পুরানো রেকর্ড মুছে ফেলার প্রয়োজন ছাড়াই পুনরায় নিবন্ধন করুন।
ঐচ্ছিক: একটি ম্যাচার তৈরি করুন
ম্যাচার হলো একটি Wasm বাইনারি যা ক্রেডেনশিয়াল ম্যানেজার একটি স্যান্ডবক্সে চালায় যাতে আপনার নিবন্ধিত ক্রেডেনশিয়ালগুলি আগত যাচাইকারী অনুরোধের বিরুদ্ধে ফিল্টার করা যায়।
- ডিফল্ট ম্যাচার:
OpenId4VpRegistryক্লাসটি স্বয়ংক্রিয়ভাবে ডিফল্টOpenId4VPম্যাচার (OpenId4VpDefaults.DEFAULT_MATCHER) অন্তর্ভুক্ত করে যখন আপনি এটি ইনস্ট্যান্ট করেন। সমস্ত স্ট্যান্ডার্ড OpenID4VP ব্যবহারের ক্ষেত্রে, লাইব্রেরি আপনার জন্য ম্যাচিং পরিচালনা করে। - কাস্টম ম্যাচার: আপনি কেবল তখনই একটি কাস্টম ম্যাচার বাস্তবায়ন করবেন যদি আপনি এমন একটি অ-মানক প্রোটোকল সমর্থন করেন যার নিজস্ব ম্যাচিং লজিক প্রয়োজন।
একটি নির্বাচিত শংসাপত্র পরিচালনা করুন
যখন একজন ব্যবহারকারী একটি ক্রেডেনশিয়াল নির্বাচন করেন, তখন আপনার হোল্ডার অ্যাপটিকে অনুরোধটি পরিচালনা করতে হবে। আপনাকে এমন একটি অ্যাক্টিভিটি নির্ধারণ করতে হবে যা androidx.credentials.registry.provider.action.GET_CREDENTIAL ইন্টেন্ট ফিল্টারটি শোনে। আমাদের নমুনা ওয়ালেট এই পদ্ধতিটি প্রদর্শন করে ।
ইনটেন্টটি আপনার কার্যকলাপকে Verifier অনুরোধ এবং কলিং অরিজিন দিয়ে শুরু করে, যা আপনি PendingIntentHandler.retrieveProviderGetCredentialRequest ফাংশন দিয়ে এক্সট্র্যাক্ট করেন । এটি একটি ProviderGetCredentialRequest প্রদান করে যেখানে যাচাইকারী অনুরোধের সাথে সম্পর্কিত সমস্ত তথ্য থাকে। তিনটি মূল উপাদান রয়েছে:
- কলিং অ্যাপ: যে অ্যাপটি অনুরোধটি করেছে,
getCallingAppInfoদিয়ে পুনরুদ্ধার করা যাবে। - নির্বাচিত শংসাপত্র: ব্যবহারকারী কোন প্রার্থীকে বেছে নিয়েছেন সে সম্পর্কে তথ্য,
selectedCredentialSet extension methodমাধ্যমে পুনরুদ্ধার করা হয়েছে; এটি আপনার নিবন্ধিত শংসাপত্র আইডির সাথে মিলবে। - নির্দিষ্ট অনুরোধ: যাচাইকারী কর্তৃক করা নির্দিষ্ট অনুরোধ,
getCredentialOptionsপদ্ধতি থেকে পুনরুদ্ধার করা হয়েছে। একটি ডিজিটাল ক্রেডেনশিয়াল অনুরোধ প্রবাহের জন্য, আপনি এই তালিকায় একটি এককGetDigitalCredentialOptionখুঁজে পাওয়ার আশা করতে পারেন।
সাধারণত, যাচাইকারী একটি ডিজিটাল শংসাপত্র উপস্থাপনার অনুরোধ করে, যা আপনি নিম্নলিখিত নমুনা কোড দিয়ে প্রক্রিয়া করতে পারেন:
request.credentialOptions.forEach { option ->
if (option is GetDigitalCredentialOption) {
Log.i(TAG, "Got DC request: ${option.requestJson}")
processRequest(option.requestJson)
}
}
এর একটি উদাহরণ নমুনা ওয়ালেটে দেখা যাবে।
যাচাইকারীর পরিচয় পরীক্ষা করুন
- উদ্দেশ্য থেকে
ProviderGetCredentialRequestবের করুন:
val request = PendingIntentHandler.retrieveProviderGetCredentialRequest(intent)
- প্রিভিলেজড অরিজিন পরীক্ষা করুন: প্রিভিলেজড অ্যাপগুলি (ওয়েব ব্রাউজারগুলির মতো) অরিজিন প্যারামিটার সেট করে অন্যান্য যাচাইকারীর পক্ষে কল করতে পারে। এই অরিজিনটি পুনরুদ্ধার করতে, আপনাকে
CallingAppInfoএরgetOrigin()API-তে প্রিভিলেজড এবং বিশ্বস্ত কলকারীদের একটি তালিকা (JSON ফর্ম্যাটে একটি allow তালিকা) পাস করতে হবে।
val origin = request?.callingAppInfo?.getOrigin(
privilegedAppsJson // Your allow list JSON
)
যদি অরিজিন খালি না থাকে: যদি signingInfo থেকে প্রাপ্ত packageName এবং সার্টিফিকেটের আঙুলের ছাপ getOrigin() API-তে পাস করা allow তালিকায় পাওয়া কোনও অ্যাপের সাথে মিলে যায়, তাহলে অরিজিন ফেরত দেওয়া হবে। অরিজিন মান পাওয়ার পর, প্রোভাইডার অ্যাপটিকে এটিকে একটি বিশেষাধিকারপ্রাপ্ত কল হিসেবে বিবেচনা করা উচিত এবং কলিং অ্যাপের স্বাক্ষর ব্যবহার করে অরিজিন গণনা করার পরিবর্তে OpenID4VP প্রতিক্রিয়াতে এই অরিজিন সেট করা উচিত।
গুগল পাসওয়ার্ড ম্যানেজার getOrigin() এ কল করার জন্য একটি উন্মুক্তভাবে উপলব্ধ অনুমতি তালিকা ব্যবহার করে। একটি শংসাপত্র প্রদানকারী হিসাবে, আপনি এই তালিকাটি ব্যবহার করতে পারেন অথবা API দ্বারা বর্ণিত JSON ফর্ম্যাটে আপনার নিজস্ব তালিকা প্রদান করতে পারেন। কোন তালিকাটি ব্যবহার করা হবে তা নির্বাচন করা সরবরাহকারীর উপর নির্ভর করে। তৃতীয় পক্ষের শংসাপত্র প্রদানকারীদের সাথে বিশেষাধিকার অ্যাক্সেস পেতে, তৃতীয় পক্ষের দ্বারা সরবরাহিত ডকুমেন্টেশন দেখুন।
যদি origin খালি থাকে, তাহলে যাচাইকারীর অনুরোধটি একটি Android অ্যাপ থেকে এসেছে। OpenID4VP প্রতিক্রিয়ায় যে অ্যাপ অরিজিনটি রাখতে হবে android:apk-key-hash:<encoded SHA 256 fingerprint> হিসাবে গণনা করা উচিত।
val appSigningInfo = request?.callingAppInfo?.signingInfoCompat?.signingCertificateHistory[0]?.toByteArray()
val md = MessageDigest.getInstance("SHA-256")
val certHash = Base64.encodeToString(md.digest(appSigningInfo), Base64.NO_WRAP or Base64.NO_PADDING)
return "android:apk-key-hash:$certHash"
হোল্ডার UI রেন্ডার করুন
যখন একটি শংসাপত্র নির্বাচন করা হয়, তখন ধারক অ্যাপটি আহ্বান করা হয়, যা ব্যবহারকারীকে অ্যাপের UI এর মাধ্যমে পরিচালিত করে। এই কর্মপ্রবাহ পরিচালনা করার দুটি আদর্শ উপায় রয়েছে:
- যদি শংসাপত্র প্রকাশের জন্য অতিরিক্ত ব্যবহারকারী প্রমাণীকরণের প্রয়োজন হয়, তাহলে BiometricPrompt API ব্যবহার করুন। এটি নমুনায় প্রদর্শিত হয়েছে।
- অন্যথায়, অনেক ওয়ালেট একটি খালি কার্যকলাপ রেন্ডার করে নীরব রিটার্ন বেছে নেয় যা তাৎক্ষণিকভাবে ডেটা কলিং অ্যাপে ফেরত পাঠায়। এটি ব্যবহারকারীর ক্লিক কমিয়ে দেয় এবং আরও নির্বিঘ্ন অভিজ্ঞতা প্রদান করে।
শংসাপত্রের উত্তরটি ফেরত দিন
আপনার হোল্ডার অ্যাপটি ফলাফল ফেরত পাঠানোর জন্য প্রস্তুত হয়ে গেলে, ক্রেডেনশিয়াল প্রতিক্রিয়া দিয়ে কার্যকলাপটি শেষ করুন:
PendingIntentHandler.setGetCredentialResponse(
resultData,
GetCredentialResponse(DigitalCredential(response.responseJson))
)
setResult(RESULT_OK, resultData)
finish()
যদি কোন ব্যতিক্রম থাকে, তাহলে আপনি একইভাবে শংসাপত্র ব্যতিক্রম পাঠাতে পারেন:
PendingIntentHandler.setGetCredentialException(
resultData,
GetCredentialUnknownException() // Configure the proper exception
)
setResult(RESULT_OK, resultData)
finish()
প্রসঙ্গে শংসাপত্রের প্রতিক্রিয়া ফেরত দেওয়ার সম্পূর্ণ উদাহরণের জন্য নমুনা অ্যাপটি দেখুন।