Статьи

Учебник по аутентификации по отпечаткам пальцев Android

Аутентификация по отпечатку пальца Android использует сенсорный датчик смартфона для аутентификации пользователя. Android Marshmallow представила набор API, который упрощает использование сенсорного датчика. До Android Marshmallow метод доступа к сенсорному сенсору не был стандартным.

Есть несколько преимуществ использования аутентификации по отпечаткам пальцев Android:

  • Быстрый и простой в использовании
  • Безопасный: отпечаток пальца однозначно идентифицирует вас
  • Онлайн транзакции безопаснее

Есть несколько шагов, которые вы должны выполнить, прежде чем использовать аутентификацию по отпечатку пальца Android, и в начале это может показаться очень сложным, но это руководство поможет вам шаг за шагом.

Конечным результатом является приложение для Android, которое использует аутентификацию по отпечатку пальца, как показано ниже:

android_fingerprint_authentication-576x1024

Начало работы с аутентификацией по отпечатку пальца Android

Как уже было сказано, для включения аутентификации по отпечатку пальца необходимо выполнить несколько шагов:

  • Убедитесь, что экран блокировки безопасен, или, другими словами, он защищен PIN-кодом, паролем или шаблоном
  • Убедитесь, что на смартфоне зарегистрирован хотя бы один отпечаток
  • Получить доступ к хранилищу ключей Android для хранения ключа, используемого для шифрования / дешифрования объекта
  • Генерация ключа шифрования и шифра
  • Запустите процесс аутентификации
  • Реализуйте класс обратного вызова для обработки событий аутентификации

Это все !! .. Мы выполним эти шаги.

Перед началом работы важно запросить разрешение на использование сенсорного датчика и аутентификацию по отпечатку пальца. Итак, в Manifest.xml мы добавляем:

1
<uses-permission android:name="android.permission.USE_FINGERPRINT" />

Теперь пришло время создать наш основной класс активности, который обрабатывает весь процесс аутентификации.

Проверьте безопасный экран блокировки в Android

Первый шаг — проверка экрана безопасной блокировки. Это может быть сделано KeyguardManager и FingerprintManager. Мы получаем экземпляр этих двух менеджеров, используя getSystemService:

1
2
3
4
5
6
7
// Keyguard Manager
KeyguardManager keyguardManager = (KeyguardManager)
                  getSystemService(KEYGUARD_SERVICE);
 
// Fingerprint Manager
fingerprintManager = (FingerprintManager)
                 getSystemService(FINGERPRINT_SERVICE);

Теперь наше приложение аутентификации может проверить, выполнены ли все условия безопасности:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private boolean checkFinger() {
 
  // Keyguard Manager
  KeyguardManager keyguardManager = (KeyguardManager)
           getSystemService(KEYGUARD_SERVICE);
 
  // Fingerprint Manager
  fingerprintManager = (FingerprintManager)
         getSystemService(FINGERPRINT_SERVICE);
 
  try {
   // Check if the fingerprint sensor is present
   if (!fingerprintManager.isHardwareDetected()) {
     // Update the UI with a message
     message.setText("Fingerprint authentication not supported");
     return false;
   }
 
   if (!fingerprintManager.hasEnrolledFingerprints()) {
     message.setText("No fingerprint configured.");
     return false;
   }
 
   if (!keyguardManager.isKeyguardSecure()) {
     message.setText("Secure lock screen not enabled");
     return false;
   }
 }
 catch(SecurityException se) {
   se.printStackTrace();
 }
 return true;
}

Обратите внимание, что приложение аутентификации проверяет, что, по крайней мере, один отпечаток пальца зарегистрирован, иначе процесс аутентификации не может начаться.

Изображение ниже показывает сообщение об ошибке, когда приложение не находит зарегистрированный отпечаток пальца.

android_fingerprint_not_supported-576x1024

Если все в порядке и все условия выполнены, приложение аутентификации генерирует ключ и получает доступ к магазину Android.

android_fingerprint_authentication-576x1024

Доступ к Android keystore и генерация ключа

Следующим шагом является доступ к хранилищу ключей Android и создание ключа для шифрования данных. Приложение делает это в отдельном методе, который называется generateKey ().

1
2
// Get the reference to the key store
keyStore = KeyStore.getInstance("AndroidKeyStore");

тогда нужно получить ссылку на генератор ключей:

1
2
3
// Key generator to generate the key
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
                 "AndroidKeyStore");

и, наконец, мы должны инициализировать генератор ключей:

01
02
03
04
05
06
07
08
09
10
11
keyGenerator.init( new
  KeyGenParameterSpec.Builder(KEY_NAME,
  KeyProperties.PURPOSE_ENCRYPT |
  KeyProperties.PURPOSE_DECRYPT)
  .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
  .setUserAuthenticationRequired(true)
  .setEncryptionPaddings(
    KeyProperties.ENCRYPTION_PADDING_PKCS7)
  .build());
 
 keyGenerator.generateKey();

Обратите внимание, что мы указываем использование ключа: encrypt и decrypt и что для использования самого ключа требуется аутентификация. В конце приложение генерирует ключ (последняя строка).

Ниже полный метод:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private void generateKey() throws FingerprintException {
  try {
    // Get the reference to the key store
    keyStore = KeyStore.getInstance("AndroidKeyStore");
 
    // Key generator to generate the key
    keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
 
      "AndroidKeyStore");
 
     keyStore.load(null);
     keyGenerator.init( new
       KeyGenParameterSpec.Builder(KEY_NAME,
      KeyProperties.PURPOSE_ENCRYPT |
      KeyProperties.PURPOSE_DECRYPT)
     .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
     .setUserAuthenticationRequired(true)
     .setEncryptionPaddings(
        KeyProperties.ENCRYPTION_PADDING_PKCS7)
    .build());
 
    keyGenerator.generateKey();
  }
  catch(KeyStoreException
   | NoSuchAlgorithmException
   | NoSuchProviderException
   | InvalidAlgorithmParameterException
   | CertificateException
   | IOException exc) {
    exc.printStackTrace();
    throw new FingerprintException(exc);
 }
}

Создать Android-шифр

Когда ключ готов, последним шагом является создание Android- шифра, который использует ключ, который мы сгенерировали ранее. Исходный код очень прост:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
private Cipher generateCipher() throws FingerprintException {
  try {
    Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
     + KeyProperties.BLOCK_MODE_CBC + "/"
     + KeyProperties.ENCRYPTION_PADDING_PKCS7);
     SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
             null);
     cipher.init(Cipher.ENCRYPT_MODE, key);
     return cipher;
  }
  catch (NoSuchAlgorithmException
     | NoSuchPaddingException
     | InvalidKeyException
     | UnrecoverableKeyException
     | KeyStoreException exc) {
      exc.printStackTrace();
      throw new FingerprintException(exc);
  }
}

Создайте приложение для Android по отпечаткам пальцев

Настало время собрать все эти методы и создать приложение для аутентификации по отпечаткам пальцев Android. Это приложение очень простое и имеет MainClass который вызывает методы, показанные выше, и запускает процесс аутентификации.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 
  message = (TextView) findViewById(R.id.fingerStatus);
  Button btn = (Button) findViewById(R.id.authBtn);
 
  final FingerprintHandler fph = new FingerprintHandler(message);
 
  if (!checkFinger()) {
    btn.setEnabled(false);
  }
  else {
    // We are ready to set up the cipher and the key
   try {
     generateKey();
     Cipher cipher = generateCipher();
     cryptoObject =
      new FingerprintManager.CryptoObject(cipher);
  }
  catch(FingerprintException fpe) {
   // Handle exception
   btn.setEnabled(false);
  }
 }
 
 btn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    message.setText("Swipe your finger");
    fph.doAuth(fingerprintManager, cryptoObject);
   }
  });
}

Есть несколько вещей, на которые стоит обратить внимание. Прежде всего, приложение Android создает CryptoObject который используется в процессе аутентификации. Кроме того, приложение показывает кнопку, и когда пользователь нажимает на нее, начинается процесс аутентификации. Кнопка отключена, если начальные условия, описанные выше, не выполнены. Самая важная вещь, на которую стоит обратить внимание, — это новый класс FingerprintHandler . Этот класс является классом обратного вызова, который получает события процесса аутентификации. Кроме того, этот класс запускает процесс аутентификации с помощью метода doAuth.

Обратный вызов аутентификации по отпечатку пальца Android

Последний шаг — создание класса обратного вызова, чтобы мы могли получать уведомления о событиях и знать, когда аутентификация прошла успешно или что-то пошло не так. Этот класс расширяет FingerprintManager .AuthenticationCallback .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
  private TextView tv;
 
  public FingerprintHandler(TextView tv) {
    this.tv = tv;
  }
 
  @Override
  public void onAuthenticationError(int errorCode, CharSequence errString) {
    super.onAuthenticationError(errorCode, errString);
    tv.setText("Auth error");
  }
 
  @Override
  public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
    super.onAuthenticationHelp(helpCode, helpString);
  }
 
  @Override
  public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
    super.onAuthenticationSucceeded(result);
    tv.setText("auth ok");
    tv.setTextColor(tv.getContext().getResources().
                getColor(android.R.color.holo_green_light));
  }
 
  @Override
  public void onAuthenticationFailed() {
    super.onAuthenticationFailed();
  }
 
  public void doAuth(FingerprintManager manager,
                     FingerprintManager.CryptoObject obj) {
   CancellationSignal signal = new CancellationSignal();
 
   try {
    manager.authenticate(obj, signal, 0, this, null);
   }
   catch(SecurityException sce) {}
 }
}

Есть несколько важных способов заметить. Прежде всего, doAuth, который запускает процесс аутентификации. Этот метод имеет CryptoObject, сигнал отмены и прослушиватель обратного вызова (этот класс). Изображение ниже показывает приложение в действии:

android_authentication_with_finger-576x1024

В этом случае пользователь проходит аутентификацию с использованием аутентификации по отпечатку пальца Android .

Как протестировать приложение в эмуляторе Android

Для тестирования приложения можно использовать реальное устройство с сенсорным сенсором. В любом случае, приложение можно протестировать и в эмуляторе. Перед тем, как начать использовать приложение, вам необходимо настроить доступ к меню «Безопасность» по отпечатку пальца. Когда система запрашивает отпечаток пальца, вы должны использовать команду adb для эмуляции касания пальцем:

1
adb -e emu finger touch id(like 1,2, ecc.)

Наконец, когда настройка завершена, вы получите сообщение, показанное ниже:

android_fingerprint_config-1-576x1024

Надеемся, что в конце этого поста вы узнали об API-интерфейсе для Android-отпечатков пальцев и о том, как разработать пример приложения для Android-приложений.