Android Protected Confirmation

อุปกรณ์ที่รองรับซึ่งใช้ Android 9 (API ระดับ 28) ขึ้นไปจะช่วยให้คุณใช้ Android Protected Confirmation ได้ เพื่อช่วยยืนยันความตั้งใจของผู้ใช้เมื่อเริ่มทำธุรกรรมที่มีความละเอียดอ่อน เช่น การชำระเงิน เมื่อใช้เวิร์กโฟลว์นี้ แอปจะแสดงข้อความแจ้งต่อผู้ใช้เพื่อขอให้ผู้ใช้รับรองข้อความสั้นๆ ที่ยืนยันความตั้งใจที่จะทำธุรกรรมที่มีความละเอียดอ่อนให้เสร็จสมบูรณ์

หากผู้ใช้ยอมรับข้อความ แอปจะใช้คีย์จาก Android Keystore เพื่อลงนามข้อความที่แสดงในกล่องโต้ตอบได้ ลายเซ็นจะระบุด้วยความม��่นใจสูงมากว่าผู้ใช้ได้อ่านข้อความและยอมรับข้อความดังกล่าว

ข้อควรระวัง: การยืนยันที่ได้รับการปกป้องของ Android ไม่ได้ให้ ช่องทางข้อมูลที่ปลอดภัยสำหรับผู้ใช้ แอปของคุณไม่สามารถถือว่ามีการรับประกันการรักษาความลับใดๆ นอกเหนือจากที่แพลตฟอร์ม Android มีให้ โดยเฉพาะอย่างยิ่ง อย่าใช้เวิร์กโฟลว์นี้เพื่อแสดงข้อมูลที่ละเอียดอ่อนซึ่งคุณ จะไม่แสดงในอุปกรณ์ของผู้ใช้ตามปกติ

หลังจากที่ผู้ใช้ยืนยันข้อความแล้ว ระบบจะรับประกันความสมบูรณ์ของข้อความ แต่แอปของคุณยังคงต้องใช้การเข้ารหัสข้อมูลที่ส่งผ่านเพื่อปกป้อง การรักษาความลับของข้อความที่ลงนาม

หากต้องการให้การสนับสนุนการยืนยันตัวตนของผู้ใช้ที่มีความน่าเชื่อถือสูงในแอป ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างคีย์การลงนามแบบอสมมาตร โดยใช้คลาส KeyGenParameterSpec.Builder เมื่อสร้างคีย์ ให้ส่ง true ไปยัง setUserConfirmationRequired() นอกจากนี้ ให้เรียก setAttestationChallenge() โดยส่งค่าชาเลนจ์ที่เหมาะสมซึ่งได้รับจากฝ่ายที่เชื่อถือ

  2. ลงทะเบียนคีย์ที่สร้างขึ้นใหม่และใบรับรองการรับรองของคีย์กับ ผู้ให้บริการที่เหมาะสม

  3. ส่งรายละเอียดธุรกรรมไปยังเซิร์ฟเวอร์ แล้วให้เซิร์ฟเวอร์สร้างและส่งคืน Binary Large Object (BLOB) ของข้อมูลพิเศษ ข้อมูลเพิ่มเติมอาจรวมถึงข้อมูลที่ต้องยืนยันหรือคำแนะนำในการแยกวิเคราะห์ เช่น ภาษาของสตริงพรอมต์

    หากต้องการใช้การติดตั้งใช้งานที่ปลอดภัยยิ่งขึ้น BLOB ต้องมี Nonce ��ี่เข้ารหัสเพื่อป้องกันการโจมตีแบบรีเพลย์ และเพื่อแยกความแตกต่างของธุรกรรม

  4. ตั้งค่าออบเจ็กต์ ConfirmationCallback ที่แจ้งให้แอปทราบเมื่อผู้ใช้ยอมรับข้อความแจ้งที่แสดงใน กล่องโต้ตอบการยืนยัน

    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.
      }
    }

    หากผู้ใช้ยอมรับกล่องโต้ตอบ ระบบจะเรียก���ช้onConfirmed() callback dataThatWasConfirmed BLOB คือโครงสร้างข้อมูล CBOR ที่มีข้อความพรอมต์ที่ผู้ใช้เห็น รวมถึงข้อมูลเพิ่มเติมที่คุณส่งไปยังเครื่องมือสร้าง ConfirmationPrompt ใช้คีย์ที่สร้างไว้ก่อนหน้านี้เพื่อลงนามใน dataThatWasConfirmed BLOB จากนั้นส่ง BLOB นี้พร้อมกับ ลายเซ็นและรายละเอียดธุรกรรมกลับไปยังผู้ให้บริการที่เชื่อถือ

    หากต้องการใช้การรับประกันความปลอดภัยที่ Android Protected Confirmation มอบให้อย่างเต็มที่ ฝ่ายที่เชื่อถือต้องทำตามขั้นตอนต่อไปนี้เมื่อได้รับข้อความที่ลงชื่อแล้ว

    1. ตรวจสอบลายเซ็นในข้อความ รวมถึงห่วงโซ่ใบรับรองการรับรองของคีย์การลงนาม
    2. ตรวจสอบว่าใบรับรองการรับรองมีตั้งค่าแฟล็ก TRUSTED_CONFIRMATION_REQUIRED ซึ่งบ่งชี้ว่าคีย์การลงชื่อ ต้องมีการยืนยันจากผู้ใช้ที่เชื่อถือได้ หากคีย์การลงนามเป็นคีย์ RSA ให้ตรวจสอบว่าไม่มีพร็อพเพอร์ตี้ PURPOSE_ENCRYPT หรือ PURPOSE_DECRYPT
    3. โปรดตรวจสอบ extraData เพื่อให้แน่ใจว่าข้อความยืนยันนี้เป็นของคำขอใหม่และยังไม่ได้รับการประมวลผล ขั้นตอนนี้จะช่วยป้องกัน การโจมตีแบบเล่นซ้ำ
    4. แยกวิเคราะห์ promptText เพื่อดูข้อมูลเกี่ยวกับการดำเนินการหรือคำขอที่ยืนยันแล้ว โปรดทราบว่า promptText เป็นส่วนเดียวของข้อความที่ผู้ใช้ยืนยันจริง ผู้ให้บริการที่เชื่อถือไม่ควรสมมติว่าข้อมูลที่ต้องยืนยันซึ่งรวมอยู่ใน extraData ตรงกับ promptText
  5. เพิ่มตรรกะที่คล้ายกับที่แสดงในข้อมูลโค้ดต่อไปนี้เพื่อ��สดง กล่องโต้ตอบเอง

    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);

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการยืนยันที่ได้รับการปกป้องของ Android ได้จากแหล่งข้อมูลต่อไปนี้

บล็อก