Search code examples
javaandroidandroid-biometric-prompt

The CryptoObject in BiometricPrompt.AuthenticationResult is always null


I am using biometric authentication dialog but my cryptoObject is always null. I have a fragment but I also tried directly from the activity.

Here is my code,

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);



}

Anybody knows what I am doing wrong?


Solution

  • To get a CryptoObject from AuthenticationResult, you must first pass in a CryptoObject when you call authenticate(), like so:

    // this example uses a Cipher but your code can use signature or mac
    biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher))
    

    If you don't pass a CryptoObject when you call authenticate() then the API doesn't have one to return to you.

    Check out this blog post.