Android 9 (API düzeyi 28) veya sonraki sürümleri çalıştıran desteklenen cihazlar, ödeme yapma gibi hassas bir işlem başlatan kullanıcıların niyetlerini doğrulamanıza yardımcı olmak için Android Korumalı Onayı'nı kullanmanıza olanak tanır. Bu iş akışını kullandığınızda uygulamanız, kullanıcıya hassas işlemi tamamlama niyetini yeniden onaylayan kısa bir ifadeyi onaylamasını isteyen bir istem gösterir.
Kullanıcı ifadeyi kabul ederse uygulamanız, iletişim kutusunda gösterilen mesajı imzalamak için Android Keystore'dan bir anahtar kullanabilir. İmza, kullanıcının beyanı gördüğünü ve kabul ettiğini çok yüksek bir güvenle gösterir.
Dikkat: Android Korumalı Onayı, kullanıcı için güvenli bir bilgi kanalı sağlamaz. Uygulamanız, Android platformunun sunduğu gizlilik garantilerinin ötesinde bir garanti sunamaz. Özellikle, kullanıcının cihazında normalde göstermeyeceğiniz hassas bilgileri görüntülemek için bu iş akışını kullanmayın.
Kullanıcı mesajı onayladıktan sonra mesajın bütünlüğü sağlanır ancak uygulamanızın, imzalı mesajın gizliliğini korumak için geçiş halindeki verilerin şifrelenmesi özelliğini kullanması gerekir.
Uygulamanızda yüksek güvenceli kullanıcı onayı desteği sunmak için aşağıdaki adımları tamamlayın:
KeyGenParameterSpec.Buildersınıfını kullanarak asimetrik imzalama anahtarı oluşturun. Anahtarı oluştururkentruedeğerinisetUserConfirmationRequired()içine iletin. Ayrıca, güvenen tarafın sağladığı uygun bir sorgulama değerini iletereksetAttestationChallenge()yöntemini çağırın.Yeni oluşturulan anahtarı ve anahtarınızın onay sertifikasını uygun bağlı tarafa kaydedin.
İşlem ayrıntılarını sunucunuza gönderin ve sunucunuzun ek veriler içeren bir ikili büyük nesne (BLOB) oluşturup döndürmesini sağlayın. Ek veriler, onaylanacak verileri veya istem dizesinin yerel ayarı gibi ayrıştırma ipuçlarını içerebilir.
Daha güvenli bir uygulama için BLOB, tekrar oynatma saldırılarına karşı koruma sağlamak ve işlemleri netleştirmek için kriptografik bir tek seferlik rastgele sayı içermelidir.
Kullanıcı bir onay iletişim kutusunda gösterilen istemi kabul ettiğinde uygulamanızı bilgilendiren
ConfirmationCallbacknesnesini ayarlayın:Kotlin
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. } }
Java
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. } }
Kullanıcı iletişim kutusunu onaylarsa
onConfirmed()geri çağırma işlevi çağrılır.dataThatWasConfirmedBLOB'u, diğer ayrıntıların yanı sıra kullanıcının gördüğü istem metnini veConfirmationPromptoluşturucuya ilettiğiniz ek verileri içeren bir CBOR veri yapısıdır. BLOB'udataThatWasConfirmedimzalamak için daha önce oluşturulan anahtarı kullanın, ardından bu BLOB'u imza ve işlem ayrıntılarıyla birlikte güvenen tarafa geri gönderin.Android Korumalı Onayı'nın sunduğu güvenlik güvencesinden tam olarak yararlanmak için güvenen taraf, imzalı bir mesaj aldıktan sonra aşağıdaki adımları uygulamalıdır:
- İmzalama anahtarının onay sertifikası zincirinin yanı sıra mesajdaki imzayı da kontrol edin.
- Onay sertifikasında
TRUSTED_CONFIRMATION_REQUIREDişaretinin ayarlandığından emin olun. Bu işaret, imzalama anahtarının güvenilir kullanıcı onayı gerektirdiğini gösterir. İmzalama anahtarı bir RSA anahtarıysaPURPOSE_ENCRYPTveyaPURPOSE_DECRYPTözelliğine sahip olmadığından emin olun. - Bu onay mesajının yeni bir isteğe ait olduğundan ve henüz işlenmediğinden emin olmak için
extraDataadresini kontrol edin. Bu adım, tekrar saldırılarına karşı koruma sağlar. - Onaylanan işlem veya istek hakkında bilgi edinmek için
promptTextöğesini ayrıştırın. Kullanıcının mesajın yalnızcapromptTextkısmını onayladığını unutmayın. Onaylayan taraf,extraDataiçinde yer alan ve onaylanacak verilerinpromptTextile eşleştiğini hiçbir zaman varsaymamalıdır.
İletişim kutusunu görüntülemek için aşağıdaki kod snippet'inde gösterilene benzer bir mantık ekleyin:
Kotlin
// 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)
Java
// 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);
Ek kaynaklar
Android Korumalı Onayı hakkında daha fazla bilgi için aşağıdaki kaynakları inceleyin.