BiometricPrompt.AuthenticationResult 中的 CryptoObject 总是为空。

6
我正在使用生物识别认证对话框,但我的 cryptoObject 总是为空。我有一个 fragment,但我也尝试了直接从活动中调用。
以下是我的代码: private Handler biometricPromptHandler = new Handler();
private Executor executor = command -> biometricPromptHandler.post(command);
private void showBiometricPrompt( String title, String description,
                                 BiometricsCompatCallback compatCallback) {

    BiometricPrompt.PromptInfo promptInfo =
            new BiometricPrompt.PromptInfo.Builder()
                    .setTitle(title)
                    .setSubtitle(description)
                    .setNegativeButtonText("Cancel")
                    .build();

    BiometricPrompt biometricPrompt = new BiometricPrompt((FragmentActivity) context,
            executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode,
                                          @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            compatCallback.onAuthenticationError(errorCode, errString);
            Log.d("onAuthenticationError", ": ");
        }

        @Override
        public void onAuthenticationSucceeded(
                @NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            Log.d("result", ": "+(result.getCryptoObject()));
            BiometricPrompt.CryptoObject authenticatedCryptoObject =
                    result.getCryptoObject();
            Log.d("onAuthentionSucceeded", ": "+(authenticatedCryptoObject==null));
            if (authenticatedCryptoObject != null) {
                 cipher = authenticatedCryptoObject.getCipher();
                Log.d("onAuthentionSucceeded", ": ");
                compatCallback.onAuthenticationSuccessful(cipher);
            }else {
                Log.d("cipher", "onAuthenticationSucceeded: ");
            }

        }

        @Override
        public void onAuthenticationFailed() {
            Log.d("onAuthenticationFailed", ": ");
            super.onAuthenticationFailed();
            compatCallback.onAuthenticationFailed();
        }
    });


        biometricPrompt.authenticate(promptInfo);



}

有人知道我做错了什么吗?

2个回答

3

authenticate方法的第二个参数中提供一个Cipher,否则它将始终返回null

使用:

authenticate(PromptInfo info, CryptoObject crypto)

取代

authenticate(PromptInfo info)

请查看教程和此代码库中的示例项目。您可以使用类似以下的代码:

BiometricPrompt.CryptoObject cryptoObject = new BiometricPrompt.CryptoObject(getEncryptCipher(createKey()));
biometricPrompt.authenticate(promptInfo, cryptoObject);

使用以下方式(取决于您想要的加密方式):

private SecretKey createKey() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    String algorithm = KeyProperties.KEY_ALGORITHM_AES;
    String provider = "AndroidKeyStore";
    KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm, provider);
    KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder("MY_KEY", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            .build();

    keyGenerator.init(keyGenParameterSpec);
    return keyGenerator.generateKey();
}

private Cipher getEncryptCipher(Key key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
    String algorithm = KeyProperties.KEY_ALGORITHM_AES;
    String blockMode = KeyProperties.BLOCK_MODE_CBC;
    String padding = KeyProperties.ENCRYPTION_PADDING_PKCS7;
    Cipher cipher = Cipher.getInstance(algorithm+"/"+blockMode+"/"+padding);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return cipher;
}

我会测试你的解决方案并告诉你。 - Muhammad Rizwan

2
从AuthenticationResult获取CryptoObject,您必须在调用authenticate()时首先传入CryptoObject,如下所示:
// this example uses a Cipher but your code can use signature or mac
biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher))

如果您在调用 authenticate() 时没有传递 CryptoObject,那么API将不能返回任何结果给您。
请查看这篇博客文章

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接