# Authentication methods

# Overview

Encap supports several different authentication methods. Not every authentication method can be used on every platform.

Below you will find:

  • The supported authentication methods for Android.
  • How to use these authentication methods.
  • The names of the parameters that you need in order to activate and authenticate with these methods.

Available authentication methods

The number of authentication methods could be limited by:

  • The application configuration on the Encap server, identified by the applicationId.
  • The mobile device's hardware.
  • The mobile device's state.

# Device

Authentication method name ActivationParameter AuthenticationParameter
AuthMethod.DEVICE DeviceActivationParameter DeviceAuthParameter

The device is a single-factor authentication method. You have the option to request single-factor device activation and authentication.

This is indicated in the Encap client API in the following objects:

  • StartActivationResult
  • StartAuthenticationResult

You can access this through the lists returned by the following methods:

  • getAuthMethodsForActivation()
  • getAuthMethodsForAuthentication()

The Encap client decides whether to complete the activation or authentication request with single or two factors.

  • For single-factor activation, it passes DeviceActivationParameter to finishActivation().
  • For single-factor authentication, it passes DeviceAuthParameter to finishAuthentication().

Note

A single-factor authentication method cannot be used to add a two-factor authentication method.

You need to configure on the server which two-factor authentication methods can be used to add other two-factor authentication methods.

When you activate a two-factor authentication method, Encap will always activate the device as well.

There are only a few use cases where activating only the device makes sense, such as with a pure authenticator app.

# PIN code

Authentication method name ActivationParameter AuthenticationParameter
AuthMethod.DEVICE_PIN DevicePinActivationParameter DevicePinAuthParameter

# Activation

Our recommendation

We recommend that you activate the PIN code first so that you will always have a backup. This could be useful if:

  • Other authentication methods get invalidated or temporarily locked.
  • The user cancels Biometrics, if it is not possible for them to use it at that time.

You can add Biometrics at a later point using the addOrUpdate operation, as described in the Add or update section for Biometric Prompt.

Activating the PIN code is similar to activating a device. However, you have to set the PIN code on the activation parameter object.

The app is responsible for making the UI where the user can set a PIN code. The StartActivationResult operation can be used to present the UI in the correct way, in terms of:

  • Password type.
  • Password length.
  • Keyboard type.

You can get this information using:

Operation Description
getMinPinCodeLength() The minimum length for PIN code configured on the server.
getMaxPinCodeLength() The maximum length for PIN code configured on the server.
getPinCodeType() The type of the input field configured on the server.

Example: How to activate a PIN code

// Activation code should come from an other source, for example a web page.
controller.startActivation(activationCode, new AsyncCallback<StartActivationResult>() {
    public void onFailure(final ErrorCodeException exception) {
        // Handle the failure.
    }
    public void onSuccess(final StartActivationResult result) {
        // Ready to continue to finishActivate. See result on how to proceed.
        // PIN code should have been typed into the UI of the app, usually between the start and finish call.
        DevicePinActivationParameter activationParameter = new DevicePinActivationParameter(pinCode);
        controller.finishActivation(activationParameter, new AsyncCallback<FinishActivationResult>() {
            public void onFailure(final ErrorCodeException exception) {
                // Handle the failure.
            }
            public void onSuccess(final FinishActivationResult result) {
                // The auth method is activated.
            }
        });
    }
});

Caution

You should not store the end-user's PIN code anywhere.

# Authentication

Authenticating with a PIN code is similar to activating a PIN code. However, you use the startAuthentication and finishAuthetication operations instead.

The results of StartAuthenticationResult gives you the same information as in activation (StartActivationResult), so that you can set up the UI for PIN code input.

Example: How to authenticate with a PIN code

controller.startAuthentication(new AsyncCallback<StartAuthenticationResult>() {
    public void onFailure(final ErrorCodeException exception) {
        // Handle the failure.
    }
    public void onSuccess(final StartAuthenticationResult result) {
        // Ready to continue to finishAuthentication. See result on how to proceed.
        // PIN code should have been typed into the UI of the app, usually between the start and finish call.
        DevicePinAuthParameter authParameter = new DevicePinAuthParameter(pinCode);
        controller.finishAuthentication(authParameter, new AsyncCallback<FinishAuthenticationResult>() {
            public void onFailure(final ErrorCodeException exception) {
                // Handle the failure.
            }
            public void onSuccess(final FinishAuthenticationResult result) {
                // The auth method is activated.
            }
        });
    }
});

# Add or update (change PIN code)

You can use the addOrUpdate operation to update the PIN code. This looks similar to authenticating with a PIN code, however, you have to set the old PIN code on the AuthParameter, and the new PIN code on the ActivationParameter.

Example: How to update a PIN code

controller.startAddOrUpdate(new AsyncCallback<StartAddOrUpdateResult>() {
    @Override
    public void onFailure(ErrorCodeException errorCodeException) {
        // Handle the failure.
    }
    @Override
    public void onSuccess(StartAddOrUpdateResult result) {
        // Old and new PIN needs to come from the apps UI, usually between the start and finish call.
        AuthParameter authParameter = new DevicePinAuthParameter(oldPin);
        ActivationParameter activateParameter = new DevicePinAuthParameter(newPin);
        controller.finishAddOrUpdate(authParameter, activateParameter, new AsyncStateChangedCallback<FinishAuthenticationResult>() {
            public void onFailure(final ErrorCodeException exception) {
                // Handle the failure.
            }
            public void onSuccess(final FinishAuthenticationResult result) {
                // Successfully changed the PIN.
            }
            public void onStateChanged(EncapController.State state) {
            }
        });
    }
});

# BiometricPrompt

Authentication method name ActivationParameter AuthenticationParameter
AuthMethod.DEVICE_ANDROID_BIOMETRIC_PROMPT DeviceAndroidBiometricPromptActivationParameter DeviceAndroidBiometricPromptAuthParameter

# Overview

Biometric Prompt was introduced in Android 9. Before that, only the Fingerprint Manager was available. This was introduced in Android 6.

The Encap Android API 3.13 and higher supports the AndroidX Biometric support library, which is a recommended support library from Google that offers backward compatibility for Biometric Prompt.

This can simplify the implementation for an app, as you can implement Biometric Prompt for all devices instead of implementing Fingerprint from Android 6-8, and then Biometric Prompt for Android 9 and higher.

When the AndroidX Biometric library dependency is added to the app, the SDK will pick this up and switch the implementation; making BiometricPrompt available for Android 6 and later.

If the dependency is not added, then you can only use Biometric Prompt for Android 9 and later.

# How to implement

  1. You must enable BIOMETRIC_PROMT and an authentication method in the application configuration.

  2. Add the following entries to AndroidManifest of the app:

<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
  1. Optional: If you want to get Biometric Prompt for older devices as well, then you must add the following dependency to the Gradle build file:
implementation 'androidx.biometric:biometric:1.1.0'

Using the correct constructor

The DeviceAndroidBiometricPromptActivationParameter and DeviceAndroidBiometricPromptAuthParameter classes have the following constructors:

  • Two constructors with a Fragment or FragmentActivity parameter. You can use these with the AndroidX Biometric Prompt library.
  • Other constructors without a Fragment or FragmentActivity parameter. You can use these with the native Android BiometricPrompt.

If you use the wrong constructor, you will get an exception.

# Activation

Although we recommend that you activate a PIN code first so that you have a fallback, it is possible to activate Biometrics directly. Before you can set this up:

  • Biometrics need to be added as an authentication method in the application configuration on the Encap server, identified by the applicationId.
  • Biometrics need to be enabled on the mobile device.

To verify whether you can activate Biometrics, you can check StartActivationResult.getAuthMethodForActivation to see if the list contains AuthMethod.DEVICE_ANDROID_BIOMETRIC_PROMPT. If it does, then you are ready to finish the activation.

The activation parameters for Biometric Prompt differ from device and PIN code, and require more data to be filled out. You can control the following:

  • Title (required)
  • Subtitle
  • Description
  • Name of the negative button on the dialogue (required)

The constructor of the ActivationParameter differs depending on if you are using the AndroidX Biometric prompt library or not:

  • If you are using the library, then you should use the constructor with Fragment or FragmentActivity.
  • If you are not using the library, then use the constructor without Fragment or FragmentActivity.

Example: How to activate Biometric Prompt

// Activation code should come from an other source, for example a web page.
controller.startActivation(activationCode, new AsyncCallback<StartActivationResult>() {
    public void onFailure(final ErrorCodeException exception) {
        // Handle the failure.
    }
    public void onSuccess(final StartActivationResult result) {
        // Ready to continue to finishActivate. See result on how to proceed.
        DeviceAndroidBiometricPromptActivationParameter activationParameter = new DeviceAndroidBiometricPromptActivationParameter(context, fragment)
                .setTitle("MyTitle")
                .setSubtitle("MySubtitle")
                .setDescription("MyDescription")
                .setNegativeButtonText("Cancel");
        controller.finishActivation(activationParameter, new AsyncCallback<FinishActivationResult>() {
            public void onFailure(final ErrorCodeException exception) {
                // Handle the failure.
            }
            public void onSuccess(final FinishActivationResult result) {
                // The auth method is activated.
            }
        });
    }
});

Note

Activating Biometrics requires the user to authenticate. This differs from iOS where it is not needed during activation.

It is technically possible to turn the dialogue off on the Android platform, but we do not expose that possibility in our Encap library. This would lower the security, as the key would not be bound to the Biometrics.

# Authentication

Authenticating with Biometrics is similar to activating with Biometrics. However, you use the startAutentication and finishAuthentication instead, with DeviceAndroidBiometricPromptAuthParameter as the AuthParameter.

First, you need to make sure that Biometrics is a possible authentication method. This means that it is:

  • Configured on the server.
  • Activated and enabled on the phone.
  • In a state where it can be used.

To verify this, you can check StartAuthenticationResult.getAuthMethodForAuthentication() to see if the list contains AuthMethod.DEVICE_ANDROID_BIOMETRIC_PROMPT.

Just as with activation for Biometric Prompt, you need to fill out some additional information for the authentication parameters (AuthParameter). You can control the following:

  • Title (required)
  • Subtitle
  • Description
  • Name of the negative button on the dialogue (required)

Example: How to authenticate with Biometrics

controller.startAuthentication(new AsyncCallback<StartAuthenticationResult>() {
    public void onFailure(final ErrorCodeException exception) {
        // Handle the failure.
    }
    public void onSuccess(final StartAuthenticationResult result) {
        // Ready to continue to finishAuthentication. See result on how to proceed.
        DeviceAndroidBiometricPromptAuthParameter authParameter = new DeviceAndroidBiometricPromptAuthParameter(context, fragment)
                .setTitle("MyTitle")
                .setSubtitle("MySubtitle")
                .setDescription("MyDescription")
                .setNegativeButtonText("Cancel");
        controller.finishAuthentication(authParameter, new AsyncCallback<FinishAuthenticationResult>() {
            public void onFailure(final ErrorCodeException exception) {
                // Handle the failure.
            }
            public void onSuccess(final FinishAuthenticationResult result) {
                // The auth method is activated.
            }
        });
    }
});

# Add or update

A typical use case is to:

  1. Activate a PIN code as a fallback, as described in the Activation section for PIN code.
  2. Use the addOrUpdate operation to add Biometrics.

If you want to add a new authentication method, then you need to have a two-factor authentication method already registered.

You can add Biometrics from any two-factor authentication method, as long as it is configured in the application configuration on the Encap server, identified by the applicationId. PIN is the most commonly used authentication method for adding Biometrics.

You can verify whether you have a two-factor authentication method that can add Biometrics by checking the getAuthMethodForAuthentication() function on the returned StartAddOrUpdateResult object.

Example: How to add Biometrics from PIN

controller.startAddOrUpdate(new AsyncCallback<StartAddOrUpdateResult>() {
    @Override
    public void onFailure(ErrorCodeException errorCodeException) {
        // Handle the failure.
    }
    @Override
    public void onSuccess(StartAddOrUpdateResult result) {
        // Old and new PIN needs to come from the apps UI, usually between the start and finish call.
        // PIN code should have been typed into the UI of the app, usually between the start and finish call.
        DevicePinAuthParameter authParameter = new DevicePinAuthParameter(pinCode);
        DeviceAndroidBiometricPromptActivationParameter activationParameter = new DeviceAndroidBiometricPromptActivationParameter(context, fragment)
                .setTitle("MyTitle")
                .setSubtitle("MySubtitle")
                .setDescription("MyDescription")
                .setNegativeButtonText("Cancel");
        controller.finishAddOrUpdate(authParameter, activationParameter, new AsyncStateChangedCallback<FinishAuthenticationResult>() {
            public void onFailure(final ErrorCodeException exception) {
                // Handle the failure.
            }
            public void onSuccess(final FinishAuthenticationResult result) {
                // Successfully added Biometrics using PIN.
            }
            public void onStateChanged(EncapController.State state) {
            }
        });
    }
});

# Error handling

The error handling for Biometric Prompt is similar to regular authentication, however, you have to consider actions for the error codes of failed Biometric authentications in addition.

The isRecoverableError() operation can be used to find out whether finishAuthentication() can be called again.

Risk of data invalidation

If any of the following occur, then the Encap authentication data is invalidated and a re-activation is required:

  • Biometrics are added to the device.
  • All Biometrics are removed from the device.
  • The secure lock screen is disabled.

See error code clientErrorAuthDataInvalidated for more details.

# Fall back to PIN

A fall back to PIN code could provide a better user experience for your end-user in some use cases, instead of just failing the authentication. For example:

  • If the end-user cancels Biometric Prompt.
  • If the end-user uses the incorrect finger too many times.

# How to implement

  1. First, a PIN needs to be activated. You can verify whether PIN is an option to fall back to by looking for DEVICE_PIN:
startAuthenticationResult.getAuthMethodsForAuthentication().contains(DEVICE_PIN).
  1. Next, you need to look for the correct error codes in the OnFailure scenario in finishAuthenticaion:
    • If you only want to fall back to PIN if Biometrics have been locked, then you need to check if the error code corresponds to either:
      • clientErrorAndroidBiometricPromptErrorLockout
      • clientErrorAndroidBiometricPromptLockoutPermanent
    • If you also want to fall back to PIN if the end-user cancels the Biometric Prompt, then you also need to look for:
      • clientErrorAndroidBiometricPromptErrorCanceled
      • clientErrorAndroidBiometricPromptErrorUserCanceled

Example: How to fall back to PIN

// In OnFailure
if (canFallbackToPin() && (isLockedError(errorCode) || isCanceledError(errorCode)) {
  // Go to the PIN flow.
  // Calling startAuthentication is not needed, as we are in a retryable state.
}

Note

If the end-user uses the wrong finger too many times, then Biometrics will be locked or permanently locked. This is only a local state, and is resolved on the phone itself.

Most phones will unlock Biometrics after turning off the screen, then using a PIN code or Pattern to unlock it again.

# Migrating Fingerprint users to Biometric Prompt

It is possible to migrate your end-users who use Fingerprint to Biometric Prompt instead.

To do this, use the addOrUpdate operations with a two-factor authentication method like PIN or Fingerprint to authenticate and activate Biometrics.

# Confirmation Required

On some mobile devices, it is possible to control whether you want a button to confirm that you are authenticating with your face or not. This confirmation button is designed to prevent accidental authentication by just looking at the screen when the Biometric Prompt appears.

The activation and authentication parameter classes for BiometricPrompt are as follows:

  • DeviceAndroidBiometricPromptActivationParameter
  • DeviceAndroidBiometricPromptAuthParameter

In these classes, you can set a hint to override this setting on the mobile device. To do this, you have to set setConfirmationRequired() to either true or false.

The default value is true. It is not recommended to set to false for high-value transactions.

Note

This is just a hint to the system. The system could still ignore the hint and:

  • Show the confirmation button even though the hint is set to false.
  • Show no button even if the hint is set to true.

An alternative to this Android feature is to implement the confirmation button in your UI yourself before calling finishAuthentication() or finishActivation().

# Multiple controller scenario

If you are activating multiple registrations, but only want the end-user to confirm with Biometrics once (to activate Biometrics for all of the registrations), then you can use setSingleBiometricPromptEnabled().

To do this:

  1. For the first DeviceAndroidBiometricPromptActivationParameter object, set this to false.
  2. For the second and following controllers, set it to true.

This will allow finishActivation() to complete the activation without interaction from the end-user for the following controllers.

Note

This has to be done within a 60 seconds time period for it to work.

Last updated: 22/03/2024 15:04 UTC