Konfirmasi Dilindungi oleh Android

Perangkat didukung yang menjalankan Android 9 (API level 28) atau yang lebih baru memberikan Anda kemampuan untuk menggunakan Konfirmasi Dilindungi oleh Android. Saat menggunakan alur kerja ini, aplikasi Anda menampilkan peringatan ke pengguna, meminta mereka untuk menyetujui pernyataan singkat. Pernyataan ini memungkinkan aplikasi untuk menegaskan bahwa pengguna ingin menyelesaikan transaksi yang sensitif, misalnya melakukan pembayaran.

Jika pengguna menyetujui pernyataan tersebut, aplikasi Anda dapat menggunakan kunci dari Android Keystore untuk menandatangani pesan yang ditampilkan dalam dialog. Tanda tangan tersebut menunjukkan, dengan keyakinan sangat tinggi, bahwa pengguna telah melihat pernyataan tersebut dan telah menyetujuinya.

Perhatian: Konfirmasi Dilindungi oleh Android tidak menyediakan saluran informasi yang aman bagi pengguna. Aplikasi Anda tidak bisa menganggap bahwa ada jaminan kerahasiaan selain yang ditawarkan oleh platform Android. Secara khusus, jangan gunakan alur kerja ini untuk menampilkan informasi sensitif yang biasanya tidak akan Anda tampilkan pada perangkat pengguna.

Setelah pengguna mengonfirmasi pesan, integritasnya akan terjamin, tetapi aplikasi Anda tetap harus menggunakan enkripsi data dalam transit untuk menjaga kerahasiaan pesan yang telah ditandatangani.

Untuk memberikan dukungan konfirmasi pengguna dengan kepastian tinggi, selesaikan langkah-langkah berikut:

  1. Buat kunci penandatanganan asimetris menggunakan class KeyGenParameterSpec.Builder. Saat membuat kunci, teruskan true ke dalam setUserConfirmationRequired(). Selain itu, panggil setAttestationChallenge(), dengan meneruskan nilai tantangan sesuai yang disediakan oleh pihak tepercaya.

  2. Daftarkan kunci yang baru dibuat dan sertifikat pengesahan kunci Anda dengan pihak tepercaya yang sesuai.

  3. Kirim detail transaksi ke server Anda dan buat agar menghasilkan serta menampikan blob data tambahan. Data tambahan mungkin termasuk data yang akan dikonfirmasi atau petunjuk penguraian, seperti lokal string perintah.

    Untuk implementasi yang lebih aman, blob harus berisi nonce kriptografis untuk perlindungan terhadap penyerangan replay dan untuk menghilangkan kerancuan transaksi.

  4. Siapkan objek ConfirmationCallback yang memberi tahu aplikasi Anda saat pengguna telah menyetujui perintah yang ditampilkan pada dialog konfirmasi:

    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
                // could respond to the prompt.
            }
    
            override fun onError(e: Exception?) {
                super.onError(e)
                // Handle the exception that the callback captured.
            }
        }
        

    Jika pengguna menyetujui dialog tersebut, callback onConfirmed() akan dipanggil. Blob dataThatWasConfirmed adalah struktur data CBOR yang berisi, di antara detail lainnya, teks permintaan yang dilihat pengguna serta data tambahan yang Anda teruskan ke builder ConfirmationPrompt. Aplikasi Anda harus menggunakan kunci yang sebelumnya dibuat untuk menandatangani blob dataThatWasConfirmed. Selanjutnya Anda harus meneruskan blob ini, bersama detail tanda tangan dan transaksi, kembali ke pihak tepercaya.

    Untuk sepenuhnya menggunakan jaminan keamanan yang ditawarkan Konfirmasi Dilindungi oleh Android, pihak tepercaya harus melakukan langkah-langkah berikut setelah menerima pesan yang ditandatangani:

    1. Periksa tanda tangan pada pesan serta rantai sertifikat pengesahan dari kunci penandatanganan.
    2. Periksa apakah sertifikat pengesahan menetapkan flag TRUSTED_CONFIRMATION_REQUIRED, yang menunjukkan bahwa kunci penandatanganan memerlukan konfirmasi pengguna tepercaya. Jika kunci penandatanganan adalah kunci RSA, periksa apakah kunci tersebut tidak memiliki properti PURPOSE_ENCRYPT atau PURPOSE_DECRYPT.
    3. Periksa extraData untuk memastikan bahwa pesan konfirmasi ini milik permintaan baru dan belum diproses. Langkah ini melindungi terhadap serangan replay.
    4. Uraikan promptText untuk informasi tentang tindakan atau permintaan yang dikonfirmasi. Ingatlah bahwa promptText adalah satu-satunya bagian dari pesan yang benar-benar dikonfirmasikan oleh pengguna. Pihak tepercaya tidak boleh berasumsi bahwa data yang harus dikonfirmasi disertakan dalam extraData sesuai dengan promptText.
  5. Tambahkan logika serupa dengan yang ditampilkan dalam cuplikan kode berikut untuk menampilkan dialog itu sendiri:

    // This data structure varies by app type. This is just 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)
        

Referensi lainnya

Untuk mengetahui informasi selengkapnya tentang Konfirmasi Dilindungi oleh Android, lihat referensi berikut.

Blog