Android Korumalı Onayı

Kullanıcılar hassas bir işlem (ör. ödeme yapma) başlattığında niyetlerini onaylamanıza yardımcı olmak için Android 9 (API düzeyi 28) veya sonraki sürümlerin yüklü olduğu desteklenen cihazlarda Android Korumalı Onayı'nı kullanabilirsiniz. Bu iş akışını kullanırken uygulamanız, kullanıcıya hassas işlemi tamamlama niyetini doğrulayan 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'daki bir anahtarı kullanabilir. İmza, kullanıcının bildirimi gördüğünü ve kabul ettiğini yüksek bir güvenle gösterir.

Dikkat: Android Protected Confirmation, kullanıcı için güvenli bir bilgi kanalı sağlamaz. Uygulamanız, Android platformunun sunduğu gizlilik garantilerinin ötesinde herhangi bir gizlilik garantisi sunamaz. Özellikle, normalde kullanıcının cihazında 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 şifrelenmesini kullanmaya devam etmesi gerekir.

Uygulamanızda yüksek güvenilirlikli kullanıcı onayı için destek sağlamak üzere aşağıdaki adımları tamamlayın:

  1. Asimetrik imzalama anahtarı oluşturmak için KeyGenParameterSpec.Builder sınıfını kullanın. Anahtarı oluştururken true değerini setUserConfirmationRequired() içine iletin. Ayrıca, güvenen tarafın sağladığı uygun bir sorgulama değeri ileterek setAttestationChallenge()'ı arayın.

  2. Yeni oluşturulan anahtarı ve anahtarınızın onay sertifikasını uygun güvenen tarafa kaydedin.

  3. İşlem ayrıntılarını sunucunuza gönderin ve sunucunuzun ek verilerin ikili büyük nesnesini (BLOB) oluşturup döndürmesini sağlayın. Ek veriler, onaylanacak verileri veya ayrıştırma ipuçlarını (ör. istem dizesinin yerel ayarı) içerebilir.

    Daha güvenli bir uygulama için BLOB, yeniden oynatma saldırılarına karşı koruma sağlamak ve işlemleri netleştirmek amacıyla kriptografik bir nonce içermelidir.

  4. Kullanıcı bir onay iletişim kutusunda gösterilen istemi kabul ettiğinde uygulamanızı bilgilendiren ConfirmationCallback nesnesini 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. dataThatWasConfirmed BLOB, kullanıcının gördüğü istem metninin yanı sıra ConfirmationPrompt oluşturucuya ilettiğiniz ek verileri de içeren bir CBOR veri yapısıdır. Daha önce oluşturulan anahtarı kullanarak dataThatWasConfirmed BLOB'u imzalayın, ardından bu BLOB'u imza ve işlem ayrıntılarıyla birlikte güvenen tarafa geri iletin.

    Android Protected Confirmation'ın sunduğu güvenlik garantisinden tam olarak yararlanmak için güvenen taraf, imzalı bir mesaj aldığında aşağıdaki adımları uygulamalıdır:

    1. İmza anahtarının onay sertifikası zincirinin yanı sıra iletideki imzayı da kontrol edin.
    2. Onay sertifikasında, imzalama anahtarının güvenilir kullanıcı onayı gerektirdiğini belirten TRUSTED_CONFIRMATION_REQUIRED işaretinin ayarlanmış olup olmadığını kontrol edin. İmzalama anahtarı bir RSA anahtarıysa PURPOSE_ENCRYPT veya PURPOSE_DECRYPT özelliğinin bulunmadığını kontrol edin.
    3. Bu onay mesajının yeni bir isteğe ait olduğundan ve henüz işlenmediğinden emin olmak için extraData işaretini kontrol edin. Bu adım, yeniden oynatma saldırılarına karşı koruma sağlar.
    4. Onaylanan işlem veya istekle ilgili bilgiler için promptText ayrıştırın. promptText, kullanıcının onayladığı tek mesaj bölümüdür. Güvenen taraf, extraData içinde onaylanacak verilerin promptText ile eşleştiğini hiçbir zaman varsaymamalıdır.
  5. Aşağıdaki kod snippet'inde gösterilene benzer bir mantık ekleyerek iletişim kutusunu görüntüleyin:

    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 Protected Confirmation hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın.

Bloglar