Аутентификация по отпечатку пальца в Android 6.0 с использованием ошибок setUserAuthentication(true)

У меня есть реализация аутентификации по отпечатку пальца, которая работала нормально, пока я не запустил ее на HTC M9+ (Android 6.0).

У меня есть ключ, сгенерированный в AndroidKeyStore:

        mKeyPairGenerator.initialize(
                new KeyGenParameterSpec.Builder(KEY_ALIAS, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
                        .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                        .setUserAuthenticationRequired(true)
                        .build());
        mKeyPairGenerator.generateKeyPair();

Затем я пытаюсь использовать это для инициализации шифра для вызова аутентификации по отпечатку пальца, и на HTC под управлением 6.0 Android я получаю сообщение об ошибке:

Crypto primitive not backed by AndroidKeyStore provider

Теперь я понимаю, что в API 23 есть ошибка, которая не позволяет использовать открытый ключ без аутентификации (хотя это и должно быть), поэтому я реализовал код для извлечения ключа из элемента AndroidKeyStore и затем его инициализации (согласно предложению в Android документация). Это работает просто отлично.

Но я не могу использовать этот извлеченный объект шифрования / шифрования с открытым ключом для вызова аутентификации отпечатка пальца:

m_fingerprintManager.authenticate(m_cryptoObject, m_cancellationSignal, 0, this, null)

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

Вот код для initCipher, извлекающего открытый ключ:

            PublicKey key = mKeyStore.getCertificate(KEY_ALIAS).getPublicKey();

            PublicKey unrestricted = KeyFactory.getInstance(key.getAlgorithm())
                    .generatePublic(new X509EncodedKeySpec(key.getEncoded()));

            OAEPParameterSpec spec = new OAEPParameterSpec(
                    "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);

            mCipher.init(opmode, unrestricted, spec);

Вот код, взятый прямо из хранилища ключей:

PrivateKey key = (PrivateKey) mKeyStore.getKey(KEY_ALIAS, null);
            mCipher.init(opmode, key);

Использование извлеченного публичного файла возвращает ошибку, что он не поддерживается AndroidKeyStore.

Использование ключа непосредственно из хранилища возвращает ошибку о том, что пользователь не аутентифицирован.

Итак, как мне заставить это работать? Как уже упоминалось, использование ключа непосредственно из хранилища ключей отлично работало на других устройствах (Samsung S7 Edge с Android M и N, Nexus 6P с N, Samsung S6 с M (6.0.1) и другие)

0 ответов

Другие вопросы по тегам