برای کمک به تأیید نیت کاربران هنگام شروع تراکنش حساس، مانند پرداخت، دستگاههای پشتیبانیشده دارای Android 9 (سطح API 28) یا بالاتر به شما امکان میدهند از تأیید محافظت شده Android استفاده کنید. هنگام استفاده از این گردش کار، برنامه شما درخواستی را به کاربر نمایش میدهد که از او میخواهد بیانیه کوتاهی را تأیید کند که مجدداً قصد آنها را برای تکمیل تراکنش حساس تأیید میکند.
اگر کاربر بیانیه را بپذیرد، برنامه شما میتواند از کلید Android Keystore برای امضای پیام نشان داده شده در کادر گفتگو استفاده کند. امضا با اطمینان بسیار بالا نشان می دهد که کاربر بیانیه را دیده و با آن موافقت کرده است.
احتیاط: تأیید محافظت شده Android یک کانال اطلاعاتی امن برای کاربر فراهم نمی کند. برنامه شما نمیتواند ضمانتهای محرمانهای را فراتر از ضمانتهایی که پلتفرم Android ارائه میدهد، در نظر بگیرد. به ویژه، از این گردش کار برای نمایش اطلاعات حساسی که معمولاً در دستگاه کاربر نشان نمیدهید استفاده نکنید.
پس از اینکه کاربر پیام را تأیید کرد، یکپارچگی پیام تضمین می شود، اما برنامه شما همچنان باید از رمزگذاری انتقال داده برای محافظت از محرمانه بودن پیام امضا شده استفاده کند.
برای ارائه پشتیبانی از تأیید کاربر با اطمینان بالا در برنامه خود، مراحل زیر را انجام دهید:
با استفاده از کلاس
KeyGenParameterSpec.Builder
یک کلید امضای نامتقارن ایجاد کنید . هنگام ایجاد کلید،true
بهsetUserConfirmationRequired()
ارسال کنید. همچنین،setAttestationChallenge()
را فراخوانی کنید و یک مقدار چالشی مناسب ارائه شده توسط طرف متکی را ارسال کنید.کلید تازه تولید شده و گواهی تایید کلید خود را نزد طرف متکی مناسب ثبت کنید.
جزئیات تراکنش را به سرور خود ارسال کنید و از آن بخواهید یک شی بزرگ باینری (BLOB) از داده های اضافی را تولید و برگرداند. دادههای اضافی ممکن است شامل دادههایی باشد که باید تأیید شوند یا نکات تجزیهکننده، مانند محل رشته اعلان.
برای اجرای ایمن تر، BLOB باید حاوی یک nonce رمزنگاری برای محافظت در برابر حملات مجدد و رفع ابهام تراکنش ها باشد.
شی
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 Protected Confirmation ارائه میدهد، طرف متکی باید پس از دریافت پیام امضا شده مراحل زیر را انجام دهد:
- امضای روی پیام و همچنین زنجیره گواهی گواهی کلید امضا را بررسی کنید.
- بررسی کنید که گواهی گواهی دارای پرچم
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، به منابع زیر مراجعه کنید.