Android Korumalı Onayı

Android 9 (API düzeyi 28) veya sonraki sürümlerin yüklü olduğu desteklenen cihazlar, ödeme yapma gibi hassas işlemler 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ışı kullanıldığında uygulamanız, kullanıcıya hassas işlemi tamamlama niyetini yeniden doğrulayan kısa bir ifadeyi onaylamasını isteyen bir istem gösterir.

Kullanıcı beyanı kabul ederse uygulamanız, iletişim kutusunda gösterilen mesajı imzalamak için Android Keystore'daki bir anahtarı kullanabilir. İmza, kullanıcının beyanı gördüğünü ve kabul ettiğini çok yüksek bir güven düzeyiyle gösterir.

Dikkat: Android Protected Confirmation, kullanıcıya güvenli bir bilgi kanalı sağlamaz. Uygulamanız, Android platformunun sunduğundan daha fazla gizlilik garantisi veremez. Özellikle, normalde kullanıcının cihazında göstermeyeceğiniz hassas bilgileri göstermek için bu iş akışını kullanmayın.

Kullanıcı iletiyi onayladıktan sonra ileti bütünlüğü sağlanır ancak uygulamanızın, imzalanmış iletilerin gizliliğini korumak için aktarma sürecindeki verileri şifrelemeye 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. KeyGenParameterSpec.Builder sınıfını kullanarak asimetrik imzalama anahtarı oluşturun. Anahtarı oluştururken true öğesini setUserConfirmationRequired() öğesine iletin. Ayrıca, setAttestationChallenge() çağrısını yapın ve ilgili tarafın sağladığı uygun meydan okuma değerini iletin.

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

  3. İşlem ayrıntılarını sunucunuza gönderin ve ek veri içeren bir ikili büyük nesne (BLOB) oluşturmasını ve döndürmesini sağlayın. Ek veriler, onaylanmak üzere olan verileri veya istem dizesinin yerel ayarı gibi ayrıştırma ipuçlarını içerebilir.

    Daha güvenli bir uygulama için BLOB'da, yeniden oynatma saldırılarına karşı koruma sağlamak ve işlemlerin anlamını açıklığa kavuşturmak amacıyla kriptografik tek kullanımlık bir değer bulunmalıdır.

  4. Kullanıcı bir onay iletişim kutusunda gösterilen isteği 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, diğer ayrıntıların yanı sıra kullanıcının gördüğü istem metnini ve ConfirmationPrompt derleyicisine aktardığınız ekstra verileri içeren bir CBOR veri yapısıdır. dataThatWasConfirmed BLOB'unu imzalamak için önceden 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 Protected Confirmation'ın sunduğu güvenlik güvencesinden tam olarak yararlanmak için güvenen tarafın, imzalı bir mesaj aldıktan sonra aşağıdaki adımları uygulaması gerekir:

    1. İletinin üzerindeki imzanın yanı sıra imzalama anahtarının doğrulama sertifikası zincirini kontrol edin.
    2. Onay sertifikasında TRUSTED_CONFIRMATION_REQUIRED iş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ıysa PURPOSE_ENCRYPT veya PURPOSE_DECRYPT mülküne sahip olmadığından emin olun.
    3. Bu onay mesajının yeni bir isteğe ait olduğundan ve henüz işlenmediğinden emin olmak için extraData seçeneğini işaretleyin. Bu adım, tekrar saldırılarına karşı koruma sağlar.
    4. Onaylanmış işlem veya istek hakkında bilgi edinmek için promptText öğesini ayrıştırın. promptText değerinin, mesajın kullanıcı tarafından onaylanan tek parçası olduğunu unutmayın. Güvenen taraf, extraData'te yer alan onaylanacak verilerin promptText'a karşılık geldiğini hiçbir zaman varsayamaz.
  5. İ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 kaynaklara göz atın.

Bloglar