แสดงกล่องโต้ตอบการตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริก

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

ตามกฎทั่วไป คุณควรใช้เครื่องมือจัดการข้อมูลเข้าสู่ระบบสำหรับการลงชื่อเข้าใช้ครั้งแรกในอุปกรณ์ การให้สิทธิ์ซ้ำครั้งต่อๆ ไปอาจทำได้ด้วยฟีเจอร์ Biometric Prompt หรือเครื่องมือจัดการข้อมูลเข้าสู่ระบบ ข้อดีของการใช้ Biometric Prompt คือมีตัวเลือกการปรับแต่งได้มากขึ้น ในขณะที่เครื่องมือจัดการข้อมูลเข้าสู่ระบบจะมีการติดตั้งใช้งานเพียงครั้งเดียวในทั้ง 2 ขั้นตอน

ประกาศประเภทการตรวจสอบสิทธิ์ที่แอปของคุณรองรับ

หากต้องการกำหนดประเภทการตรวจสอบสิทธิ์ที่แอปรองรับ ให้ใช้อินเทอร์เฟซ BiometricManager.Authenticators ระบบให้คุณประกาศการตรวจสอบสิทธิ์ประเภทต่อไปนี้ได้

BIOMETRIC_STRONG
การตรวจสอบสิทธิ์โดยใช้ข้อมูลไบโอเมตริกคลาส 3 ตามที่ระบุไว้ในหน้าคำจำกัดความความเข้ากันได้กับ Android
BIOMETRIC_WEAK
การตรวจสอบสิทธิ์โดยใช้ข้อมูลไบโอเมตริกคลาส 2 ตามที่กำหนดไว้ในหน้าคำจำกัดความความเข้ากันได้ของ Android
DEVICE_CREDENTIAL
การตรวจสอบสิทธิ์โดยใช้ข้อมูลเข้าสู่ระบบการล็อกหน้าจอ ได้แก่ PIN, รูปแบบ หรือรหัสผ่านของผู้ใช้

หากต้องการเริ่มใช้โปรแกรมตรวจสอบสิทธิ์ ผู้ใช้จะต้องสร้าง PIN, รูปแบบ หรือรหัสผ่าน หากยังไม่มี ขั้นตอนลงทะเบียนข้อมูลไบโอเมตริกจะแจ้งให้ผู้ใช้สร้างข้อมูลดังกล่าว

หากต้องการกำหนดประเภทการตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริกที่แอปยอมรับ ให้ส่งประเภทการตรวจสอบสิทธิ์หรือชุดค่าผสมของประเภทลงในเมธอด setAllowedAuthenticators() ข้อมูลโค้ดต่อไปนี้แสดงวิธีรองรับการตรวจสอบสิทธิ์โดยใช้ข้อมูลไบโอเมตริกระดับ 3 หรือข้อมูลเข้าสู่ระบบการล็อกหน้าจอ

Kotlin

// Lets the user authenticate using either a Class 3 biometric or
// their lock screen credential (PIN, pattern, or password).
promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setAllowedAuthenticators(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        .build()

Java

// Lets user authenticate using either a Class 3 biometric or
// their lock screen credential (PIN, pattern, or password).
promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
        .build();

ระบบไม่รองรับชุดค่าผสมของประเภทโปรแกรมตรวจสอบสิทธิ์ต่อไปนี้ใน Android 10 (API ระดับ 29) และต่ำกว่า DEVICE_CREDENTIAL และ BIOMETRIC_STRONG | DEVICE_CREDENTIAL หากต้องการตรวจสอบว่ามี PIN, รูปแบบ หรือรหัสผ่านใน Android 10 หรือต่ำกว่าหรือไม่ ให้ใช้วิธี KeyguardManager.isDeviceSecure()

ตรวจสอบว่ามีการตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริก

หลังจากเลือกองค์ประกอบการตรวจสอบสิทธิ์ที่แอปรองรับแล้ว ให้ตรวจสอบว่าองค์ประกอบเหล่านี้พร้อมใช้งานหรือไม่ โดยส่งการรวมประเภทแบบบิตต่อบิตเดียวกันกับที่คุณประกาศโดยใช้เมธอด setAllowedAuthenticators() ไปยังเมธอด canAuthenticate() หากจําเป็น ให้เรียกใช้การดำเนินการของ Intent ACTION_BIOMETRIC_ENROLL ใน Intent Extra ให้ระบุชุดโปรแกรมตรวจสอบสิทธิ์ที่แอปยอมรับ Intent นี้จะแจ้งให้ผู้ใช้ลงทะเบียนข้อมูลเข้าสู่ระบบสำหรับโปรแกรมตรวจสอบสิทธิ์ที่แอปของคุณยอมรับ

Kotlin

val biometricManager = BiometricManager.from(this)
when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
    BiometricManager.BIOMETRIC_SUCCESS ->
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.")
    BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
        Log.e("MY_APP_TAG", "No biometric features available on this device.")
    BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.")
    BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
        // Prompts the user to create credentials that your app accepts.
        val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
            putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        }
        startActivityForResult(enrollIntent, REQUEST_CODE)
    }
}

Java

BiometricManager biometricManager = BiometricManager.from(this);
switch (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) {
    case BiometricManager.BIOMETRIC_SUCCESS:
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
        Log.e("MY_APP_TAG", "No biometric features available on this device.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
        // Prompts the user to create credentials that your app accepts.
        final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
        enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG | DEVICE_CREDENTIAL);
        startActivityForResult(enrollIntent, REQUEST_CODE);
        break;
}

ระบุวิธีที่ผู้ใช้ตรวจสอบสิทธิ์

หลังจากผู้ใช้ตรวจสอบสิทธิ์แล้ว คุณสามารถตรวจสอบว่าผู้ใช้ตรวจสอบสิทธิ์โดยใช้ข้อมูลเข้าสู่ระบบของอุปกรณ์หรือข้อมูลเข้าสู่ระบบไบโอเมตริกโดยเรียกใช้ getAuthenticationType()

แสดงข้อความแจ้งให้เข้าสู่ระบบ

หากต้องการแสดงข้อความแจ้งของระบบที่ขอให้ผู้ใช้ตรวจสอบสิทธิ์โดยใช้ข้อมูลเข้าสู่ระบบไบโอเมตริก ให้ใช้ไลบรารีข้อมูลไบโอเมตริก กล่องโต้ตอบที่ระบบให้นี้จะสอดคล้องกันในทุกแอปที่ใช้ ซึ่งจะสร้างประสบการณ์การใช้งานที่เชื่อถือได้มากขึ้น ตัวอย่างกล่องโต้ตอบจะปรากฏในรูปที่ 1

ภาพหน้าจอแสดงกล่องโต้ตอบ
รูปที่ 1 กล่องโต้ตอบของระบบที่ขอการตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริก

หากต้องการเพิ่มการตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริกลงในแอปโดยใช้คลังข้อมูลไบโอเมตริก ให้ทำตามขั้นตอนต่อไปนี้

  1. ในไฟล์ build.gradle ของโมดูลแอป ให้เพิ่ม Dependency ของ androidx.biometric ไลบรารี

  2. ในกิจกรรมหรือส่วนย่อยที่โฮสต์กล่องโต้ตอบการเข้าสู่ระบบด้วยข้อมูลไบโอเมตริก ให้แสดงกล่องโต้ตอบโดยใช้ตรรกะที่แสดงในข้อมูลโค้ดต่อไปนี้

    Kotlin

    private lateinit var executor: Executor
    private lateinit var biometricPrompt: BiometricPrompt
    private lateinit var promptInfo: BiometricPrompt.PromptInfo
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        executor = ContextCompat.getMainExecutor(this)
        biometricPrompt = BiometricPrompt(this, executor,
                object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(errorCode: Int,
                    errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                Toast.makeText(applicationContext,
                    "Authentication error: $errString", Toast.LENGTH_SHORT)
                    .show()
            }
    
            override fun onAuthenticationSucceeded(
                    result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                Toast.makeText(applicationContext,
                    "Authentication succeeded!", Toast.LENGTH_SHORT)
                    .show()
            }
    
            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                Toast.makeText(applicationContext, "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show()
            }
        })
    
        promptInfo = BiometricPrompt.PromptInfo.Builder()
                .setTitle("Biometric login for my app")
                .setSubtitle("Log in using your biometric credential")
                .setNegativeButtonText("Use account password")
                .build()
    
        // Prompt appears when user clicks "Log in".
        // Consider integrating with the keystore to unlock cryptographic operations,
        // if needed by your app.
        val biometricLoginButton =
                findViewById<Button>(R.id.biometric_login)
        biometricLoginButton.setOnClickListener {
            biometricPrompt.authenticate(promptInfo)
        }
    }

    Java

    private Executor executor;
    private BiometricPrompt biometricPrompt;
    private BiometricPrompt.PromptInfo promptInfo;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        executor = ContextCompat.getMainExecutor(this);
        biometricPrompt = new BiometricPrompt(MainActivity.this,
                executor, new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode,
                    @NonNull CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
                Toast.makeText(getApplicationContext(),
                    "Authentication error: " + errString, Toast.LENGTH_SHORT)
                    .show();
            }
    
            @Override
            public void onAuthenticationSucceeded(
                    @NonNull BiometricPrompt.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                Toast.makeText(getApplicationContext(),
                    "Authentication succeeded!", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                Toast.makeText(getApplicationContext(), "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show();
            }
        });
    
        promptInfo = new BiometricPrompt.PromptInfo.Builder()
                .setTitle("Biometric login for my app")
                .setSubtitle("Log in using your biometric credential")
                .setNegativeButtonText("Use account password")
                .build();
    
        // Prompt appears when user clicks "Log in".
        // Consider integrating with the keystore to unlock cryptographic operations,
        // if needed by your app.
        Button biometricLoginButton = findViewById(R.id.biometric_login);
        biometricLoginButton.setOnClickListener(view -> {
                biometricPrompt.authenticate(promptInfo);
        });
    }

ใช้โซลูชันวิทยาการเข้ารหัสที่ขึ้นอยู่กับการตรวจสอบสิทธิ์

หากต้องการปกป้องข้อมูลที่ละเอียดอ่อนภายในแอปเพิ่มเติม คุณสามารถรวมการเข้ารหัสไว้ในเวิร์กโฟลว์การตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริกได้โดยใช้อินสแตนซ์ของ CryptoObject เฟรมเวิร์กรองรับออบเจ็กต์การเข้ารหัสต่อไปนี้ Signature, Cipher และ Mac

หลังจากผู้ใช้ตรวจสอบสิทธิ์โดยใช้ข้อความแจ้งข้อมูลไบโอเมตริกสำเร็จแล้ว แอปของคุณจะดำเนินการเข้ารหัสได้ ตัวอย่างเช่น หากคุณตรวจสอบสิทธิ์โดยใช้ออบเจ็กต์ Cipher แอปก็จะเข้ารหัสและถอดรหัสโดยใช้ออบเจ็กต์ SecretKey ได้

ส่วนต่อไปนี้จะแสดงตัวอย่างการใช้ออบเจ็กต์ Cipher และออบเจ็กต์ SecretKey เพื่อเข้ารหัสข้อมูล ตัวอย่างแต่ละรายการจะใช้วิธีการต่อไปนี้

Kotlin

private fun generateSecretKey(keyGenParameterSpec: KeyGenParameterSpec) {
    val keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    keyGenerator.init(keyGenParameterSpec)
    keyGenerator.generateKey()
}

private fun getSecretKey(): SecretKey {
    val keyStore = KeyStore.getInstance("AndroidKeyStore")

    // Before the keystore can be accessed, it must be loaded.
    keyStore.load(null)
    return keyStore.getKey(KEY_NAME, null) as SecretKey
}

private fun getCipher(): Cipher {
    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
            + KeyProperties.BLOCK_MODE_CBC + "/"
            + KeyProperties.ENCRYPTION_PADDING_PKCS7)
}

Java

private void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    keyGenerator.init(keyGenParameterSpec);
    keyGenerator.generateKey();
}

private SecretKey getSecretKey() {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

    // Before the keystore can be accessed, it must be loaded.
    keyStore.load(null);
    return ((SecretKey)keyStore.getKey(KEY_NAME, null));
}

private Cipher getCipher() {
    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
            + KeyProperties.BLOCK_MODE_CBC + "/"
            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
}

ตรวจสอบสิทธิ์โดยใช้ข้อมูลเข้าสู่ระบบแบบไบโอเมตริกเท่านั้น

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

หากต้องการเข้ารหัสข้อมูลที่ละเอียดอ่อนหลังจากที่ผู้ใช้ตรวจสอบสิทธิ์โดยใช้ข้อมูลเข้าสู่ระบบข้อมูลไบโอเมตริกแล้วเท่านั้น ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างคีย์ที่ใช้การกำหนดค่า KeyGenParameterSpec ต่อไปนี้

    Kotlin

    generateSecretKey(KeyGenParameterSpec.Builder(
            KEY_NAME,
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            // Invalidate the keys if the user has registered a new biometric
            // credential, such as a new fingerprint. Can call this method only
            // on Android 7.0 (API level 24) or higher. The variable
            // "invalidatedByBiometricEnrollment" is true by default.
            .setInvalidatedByBiometricEnrollment(true)
            .build())

    Java

    generateSecretKey(new KeyGenParameterSpec.Builder(
            KEY_NAME,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            // Invalidate the keys if the user has registered a new biometric
            // credential, such as a new fingerprint. Can call this method only
            // on Android 7.0 (API level 24) or higher. The variable
            // "invalidatedByBiometricEnrollment" is true by default.
            .setInvalidatedByBiometricEnrollment(true)
            .build());
  2. เริ่มเวิร์กโฟลว์การตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริกที่ใช้การเข้ารหัส โดยทำดังนี้

    Kotlin

    biometricLoginButton.setOnClickListener {
        // Exceptions are unhandled within this snippet.
        val cipher = getCipher()
        val secretKey = getSecretKey()
        cipher.init(Cipher.ENCRYPT_MODE, secretKey)
        biometricPrompt.authenticate(promptInfo,
                BiometricPrompt.CryptoObject(cipher))
    }

    Java

    biometricLoginButton.setOnClickListener(view -> {
        // Exceptions are unhandled within this snippet.
        Cipher cipher = getCipher();
        SecretKey secretKey = getSecretKey();
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        biometricPrompt.authenticate(promptInfo,
                new BiometricPrompt.CryptoObject(cipher));
    });
  3. ใน Callback ของการตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริก ให้ใช้คีย์ลับเพื่อเข้ารหัสข้อมูลที่ละเอียดอ่อน ดังนี้

    Kotlin

    override fun onAuthenticationSucceeded(
            result: BiometricPrompt.AuthenticationResult) {
        val encryptedInfo: ByteArray = result.cryptoObject.cipher?.doFinal(
            // plaintext-string text is whatever data the developer would like
            // to encrypt. It happens to be plain-text in this example, but it
            // can be anything
                plaintext-string.toByteArray(Charset.defaultCharset())
        )
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo))
    }

    Java

    @Override
    public void onAuthenticationSucceeded(
            @NonNull BiometricPrompt.AuthenticationResult result) {
        // NullPointerException is unhandled; use Objects.requireNonNull().
        byte[] encryptedInfo = result.getCryptoObject().getCipher().doFinal(
            // plaintext-string text is whatever data the developer would like
            // to encrypt. It happens to be plain-text in this example, but it
            // can be anything
                plaintext-string.getBytes(Charset.defaultCharset()));
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo));
    }

ตรวจสอบสิทธิ์โดยใช้ข้อมูลเข้าสู่ระบบหรือข้อมูลเข้าสู่ระบบบนหน้าจอล็อก

คุณใช้คีย์ลับที่อนุญาตการตรวจสอบสิทธิ์ได้โดยใช้ข้อมูลเข้าสู่ระบบไบโอเมตริกหรือข้อมูลเข้าสู่ระบบในหน้าจอล็อก (PIN, รูปแบบ หรือรหัสผ่าน) เมื่อกําหนดค่าคีย์นี้ ให้ระบุระยะเวลาที่ใช้งานได้ ในระหว่างนี้ แอปของคุณจะดำเนินการทางวิทยาการเข้ารหัสได้หลายรายการโดยไม่ต้องให้ผู้ใช้ตรวจสอบสิทธิ์อีกครั้ง

หากต้องการเข้ารหัสข้อมูลที่ละเอียดอ่อนหลังจากที่ผู้ใช้ตรวจสอบสิทธิ์โดยใช้ข้อมูลไบโอเมตริกหรือข้อมูลเข้าสู่ระบบหน้าจอล็อก ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างคีย์ที่ใช้การกำหนดค่า KeyGenParameterSpec ต่อไปนี้

    Kotlin

    generateSecretKey(KeyGenParameterSpec.Builder(
        KEY_NAME,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setUserAuthenticationParameters(VALIDITY_DURATION_SECONDS,
                ALLOWED_AUTHENTICATORS)
        .build())

    Java

    generateSecretKey(new KeyGenParameterSpec.Builder(
        KEY_NAME,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setUserAuthenticationParameters(VALIDITY_DURATION_SECONDS,
                ALLOWED_AUTHENTICATORS)
        .build());
  2. ภายในระยะเวลา VALIDITY_DURATION_SECONDS หลังจากที่ผู้ใช้ตรวจสอบสิทธิ์แล้ว ให้เข้ารหัสข้อมูลที่ละเอียดอ่อนดังนี้

    Kotlin

    private fun encryptSecretInformation() {
        // Exceptions are unhandled for getCipher() and getSecretKey().
        val cipher = getCipher()
        val secretKey = getSecretKey()
        try {
            cipher.init(Cipher.ENCRYPT_MODE, secretKey)
            val encryptedInfo: ByteArray = cipher.doFinal(
                // plaintext-string text is whatever data the developer would
                // like to encrypt. It happens to be plain-text in this example,
                // but it can be anything
                    plaintext-string.toByteArray(Charset.defaultCharset()))
            Log.d("MY_APP_TAG", "Encrypted information: " +
                    Arrays.toString(encryptedInfo))
        } catch (e: InvalidKeyException) {
            Log.e("MY_APP_TAG", "Key is invalid.")
        } catch (e: UserNotAuthenticatedException) {
            Log.d("MY_APP_TAG", "The key's validity timed out.")
            biometricPrompt.authenticate(promptInfo)
        }

    Java

    private void encryptSecretInformation() {
        // Exceptions are unhandled for getCipher() and getSecretKey().
        Cipher cipher = getCipher();
        SecretKey secretKey = getSecretKey();
        try {
            // NullPointerException is unhandled; use Objects.requireNonNull().
            ciper.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedInfo = cipher.doFinal(
                // plaintext-string text is whatever data the developer would
                // like to encrypt. It happens to be plain-text in this example,
                // but it can be anything
                    plaintext-string.getBytes(Charset.defaultCharset()));
        } catch (InvalidKeyException e) {
            Log.e("MY_APP_TAG", "Key is invalid.");
        } catch (UserNotAuthenticatedException e) {
            Log.d("MY_APP_TAG", "The key's validity timed out.");
            biometricPrompt.authenticate(promptInfo);
        }
    }

ตรวจสอบสิทธิ์โดยใช้คีย์การตรวจสอบสิทธิ์ต่อการใช้งาน

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

หากต้องการเชื่อมโยงออบเจ็กต์ BiometricPrompt กับคีย์การตรวจสอบสิทธิ์ต่อการใช้งาน ให้เพิ่มโค้ดที่คล้ายกับตัวอย่างต่อไปนี้

Kotlin

val authPerOpKeyGenParameterSpec =
        KeyGenParameterSpec.Builder("myKeystoreAlias", key-purpose)
    // Accept either a biometric credential or a device credential.
    // To accept only one type of credential, include only that type as the
    // second argument.
    .setUserAuthenticationParameters(0 /* duration */,
            KeyProperties.AUTH_BIOMETRIC_STRONG or
            KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build()

Java

KeyGenParameterSpec authPerOpKeyGenParameterSpec =
        new KeyGenParameterSpec.Builder("myKeystoreAlias", key-purpose)
    // Accept either a biometric credential or a device credential.
    // To accept only one type of credential, include only that type as the
    // second argument.
    .setUserAuthenticationParameters(0 /* duration */,
            KeyProperties.AUTH_BIOMETRIC_STRONG |
            KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build();

ตรวจสอบสิทธิ์โดยที่ผู้ใช้ไม่ต้องดำเนินการใดๆ

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

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

รูปที่ 2 แสดงกล่องโต้ตอบเดียวกัน 2 เวอร์ชัน เวอร์ชันหนึ่งกำหนดให้ผู้ใช้ดำเนินการอย่างชัดแจ้ง แต่อีกเวอร์ชันหนึ่งไม่กำหนด

ภาพหน้าจอของกล่องโต้ตอบ ภาพหน้าจอของกล่องโต้ตอบ
รูปที่ 2 การตรวจสอบสิทธิ์ด้วยใบหน้าแบบไม่ยืนยันผู้ใช้ (ด้านบน) และแบบยืนยันผู้ใช้ (ด้านล่าง)

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

Kotlin

// Lets the user authenticate without performing an action, such as pressing a
// button, after their biometric credential is accepted.
promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build()

Java

// Lets the user authenticate without performing an action, such as pressing a
// button, after their biometric credential is accepted.
promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build();

อนุญาตให้ใช้ข้อมูลเข้าสู่ระบบสำรองที่ไม่ใช่ข้อมูลไบโอเมตริก

หากต้องการให้แอปอนุญาตการตรวจสอบสิทธิ์โดยใช้ข้อมูลไบโอเมตริกหรือข้อมูลเข้าสู่ระบบของอุปกรณ์ คุณสามารถประกาศว่าแอปรองรับข้อมูลเข้าสู่ระบบของอุปกรณ์โดยใส่ DEVICE_CREDENTIAL ไว้ในชุดค่าที่คุณส่งไปยัง setAllowedAuthenticators()

หากปัจจุบันแอปใช้ createConfirmDeviceCredentialIntent() หรือ setDeviceCredentialAllowed() เพื่อให้บริการนี้ ให้เปลี่ยนไปใช้ setAllowedAuthenticators()

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

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

บล็อกโพสต์