ولمساعدتك في التأكد من هوية المستخدمين نواياه عندما يبدؤون عملية معاملة، مثل إجراء عملية دفع، على الأجهزة المتوافقة التي تعمل بنظام التشغيل Android 9 (واجهة برمجة التطبيقات 28) أو مستوى أعلى يتيح لك استخدام ميزة "التأكيد الآمن" من Android. عند استخدام هذه الميزة يعرض تطبيقك طلبًا إلى المستخدم للموافقة على فيديو Shorts يؤكّد نيته لإكمال المعاملة الحساسة.
إذا وافق المستخدم على البيان، يمكن لتطبيقك استخدام مفتاح من "مفتاح Android" لتوقيع الرسالة المعروضة في مربّع الحوار. يُشير التوقيع إلى كلمة مرتفعة جدًا من الثقة، بأن المستخدم قد شاهد البيان ووافق عليه.
تنبيه: لا توفّر ميزة "التأكيد الآمن" من Android قناة معلومات آمنة للمستخدم. لا يمكن لتطبيقك افتراض ضمانات سرية بخلاف تلك التي يوفرها نظام Android الأساسي. ضِمن على وجه الخصوص، لا تستخدم سير العمل هذا لعرض معلومات حساسة عادةً على جهاز المستخدم.
وبعد تأكيد المستخدم للرسالة، يتم ضمان سلامة الرسالة، ولكن لا يزال على تطبيقك استخدام تشفير البيانات أثناء نقلها لحماية سرية الرسالة الموقَّعة.
لتوفير ميزة تأكيد المستخدم العالية الأمان في تطبيقك، أكمِل الخطوات التالية:
أنشئ مفتاح توقيع غير متماثل باستخدام فئة
KeyGenParameterSpec.Builder
. عند إنشاء المفتاح، أدخِلtrue
فيsetUserConfirmationRequired()
يمكنك أيضًا الاتصال بالرقمsetAttestationChallenge()
، وتمرير قيمة التحدي المناسبة التي يقدمها الطرف المعتمد.سجِّل المفتاح الذي تم إنشاؤه حديثًا وشهادة مصادقة المفتاح باستخدام الطرف المعتمِد المناسب.
أرسِل تفاصيل المعاملة إلى خادمك واطلب منه إنشاء ملف ملف بيانات إضافية وعرضه. قد تتضمّن البيانات الإضافية data التي يجب تأكيدها أو نصائح التحليل، مثل لغة سلسلة الطلب.
لتنفيذ أكثر أمانًا، يجب أن يحتوي BLOB على رمز مفتاح تشفير عشوائي للحماية من هجمات إعادة التشغيل وإزالة الغموض عن المعاملات.
إعداد
ConfirmationCallback
عنصر يخبر تطبيقك عند قبول المستخدم الطلب المعروض في مربع حوار التأكيد:class MyConfirmationCallback : ConfirmationCallback() { override fun onConfirmed(dataThatWasConfirmed: ByteArray?) { super.onConfirmed(dataThatWasConfirmed) // Sign dataThatWasConfirmed using your generated signing key. // By completing this process, you generate a signed statement. } override fun onDismissed() { super.onDismissed() // Handle case where user declined the prompt in the // confirmation dialog. } override fun onCanceled() { super.onCanceled() // Handle case where your app closed the dialog before the user // responded to the prompt. } override fun onError(e: Exception?) { super.onError(e) // Handle the exception that the callback captured. } }
public class MyConfirmationCallback extends ConfirmationCallback { @Override public void onConfirmed(@NonNull byte[] dataThatWasConfirmed) { super.onConfirmed(dataThatWasConfirmed); // Sign dataThatWasConfirmed using your generated signing key. // By completing this process, you generate a signed statement. } @Override public void onDismissed() { super.onDismissed(); // Handle case where user declined the prompt in the // confirmation dialog. } @Override public void onCanceled() { super.onCanceled(); // Handle case where your app closed the dialog before the user // responded to the prompt. } @Override public void onError(Throwable e) { super.onError(e); // Handle the exception that the callback captured. } }
إذا وافق المستخدم على مربّع الحوار، يتم استدعاء
onConfirmed()
. تُعد كائنdataThatWasConfirmed
BLOB تحتوي هيكل بيانات CBOR على بالإضافة إلى تفاصيل أخرى، نص المطالبة الذي رآه المستخدم، بالإضافة إلى البيانات التي مررت بها إلىConfirmationPrompt
البنّاء. استخدم المفتاح الذي تم إنشاؤه مسبقًا لتوقيعdataThatWasConfirmed
BLOB، ثم تمرير BLOB هذه مع تفاصيل المعاملة والتوقيع إلى الطرف المعتمِد.للاستفادة بشكل كامل من ضمان الأمان الذي يوفّره "تأكيد Android المحمي"، على الجهة المُعتمَدة اتّباع الخطوات التالية عند تلقّي رسالة موقَّعة:
- تحقَّق من التوقيع على الرسالة بالإضافة إلى سلسلة شهادات التحقّق لمفتاح التوقيع.
- التحقق من احتواء شهادة المصادقة على
تم ضبط علامات
TRUSTED_CONFIRMATION_REQUIRED
، والتي تشير إلى أنّ التوقيع تأكيدًا من مستخدم موثوق به. إذا كان مفتاح التوقيع هو مفتاح RSA، تحقَّق من أنّه لا يتضمّن القيمةPURPOSE_ENCRYPT
أوPURPOSE_DECRYPT
. - يُرجى مراجعة
extraData
للتأكد من أن رسالة التأكيد هذه تخص طلب جديد ولم تتم معالجته بعد. تحمي هذه الخطوة من هجمات تسجيل الجلسات. - يمكنك تحليل
promptText
للحصول على معلومات عن الإجراء الذي تم تأكيده أو طلبك. تذكر أنpromptText
هو الجزء الوحيد من الرسالة الذي أكدها المستخدم بالفعل. يجب ألا يفترض الطرف المُعتمِد أبدًا أنّ البيانات التي يجب تأكيدها والمضمّنة فيextraData
تتطابق معpromptText
.
أضِف منطقًا مشابهًا لما هو معروض في مقتطف الرمز التالي لعرض مربع الحوار نفسه:
// This data structure varies by app type. This is an example. data class ConfirmationPromptData(val sender: String, val receiver: String, val amount: String) val myExtraData: ByteArray = byteArrayOf() val myDialogData = ConfirmationPromptData("Ashlyn", "Jordan", "$500") val threadReceivingCallback = Executor { runnable -> runnable.run() } val callback = MyConfirmationCallback() val dialog = ConfirmationPrompt.Builder(context) .setPromptText("${myDialogData.sender}, send ${myDialogData.amount} to ${myDialogData.receiver}?") .setExtraData(myExtraData) .build() dialog.presentPrompt(threadReceivingCallback, callback)
// This data structure varies by app type. This is an example. class ConfirmationPromptData { String sender, receiver, amount; ConfirmationPromptData(String sender, String receiver, String amount) { this.sender = sender; this.receiver = receiver; this.amount = amount; } }; final int MY_EXTRA_DATA_LENGTH = 100; byte[] myExtraData = new byte[MY_EXTRA_DATA_LENGTH]; ConfirmationPromptData myDialogData = new ConfirmationPromptData("Ashlyn", "Jordan", "$500"); Executor threadReceivingCallback = Runnable::run; MyConfirmationCallback callback = new MyConfirmationCallback(); ConfirmationPrompt dialog = (new ConfirmationPrompt.Builder(getApplicationContext())) .setPromptText("${myDialogData.sender}, send ${myDialogData.amount} to ${myDialogData.receiver}?") .setExtraData(myExtraData) .build(); dialog.presentPrompt(threadReceivingCallback, callback);
مصادر إضافية
لمزيد من المعلومات عن ميزة "التأكيد المحمي" في Android، يُرجى الرجوع إلى المراجع التالية: