Using Custom Passcode Vaults
Overview
Identity Vault allows you to create a Custom Passcode vault. With a custom passcode vault, your application needs to provide the mechanism used to collect the passcode from the user. The passcode is then used to generate a key that is used to lock and unlock the vault. The passcode is only used to generate a key, it is never stored anywhere by Identity Vault. Since the passcode is not stored, it cannot be stolen.
You can think of it working like this:
- When the vault is created, the user supplies a passcode.
- The passcode is used to generate a key and the passcode is discarded.
- This key becomes part of the current vault configuration so the vault can later be locked.
- When the vault is locked the key is destroyed, resulting in a new key being required to unlock the vault.
- When the user wants to unlock the vault, they supply a passcode.
- The passcode is used to generate a key and the passcode is discarded.
- If the new passcode was the same as the original passcode, the new key matches the old key and unlocks the vault, otherwise it does not.
The important items are: the passcode does not live beyond generating a key and the key does not live beyond locking the vault.
Let's Code
This tutorial builds upon the application created when doing the startup strategies tutorial. If you have the code from when you performed that tutorial, then you are ready to go. If you need the code you can make a copy from our GitHub repository.
Update the Vault Type
Add CustomPasscode
to the UnlockMode
.
Update the calculation that determines the type
for the vault.
We need to handle the workflow when the vault needs to request a custom passcode. Return a hard-coded value for now.
Create a button on Tab1Page
to use the custom passcode.
Add CustomPasscode
to the UnlockMode
.
Update the calculation that determines the type
for the vault.
We need to handle the workflow when the vault needs to request a custom passcode. Return a hard-coded value for now.
Create a button on Tab1Page
to use the custom passcode.
Create Passcode workflow
When you are using a Custom Passcode, the type of passcode along with the strategies used to gather it are up to you.
Workflows are used to accomplish two distinct tasks:
- Create the passcode that is used to lock the vault.
- Obtain the passcode that is used to attempt to unlock the vault.
The basic elements for all workflows is:
- Respond to the onPasscodeRequested event.
- Gather the passcode.
- Either use the
onComplete
callback from the onPasscodeRequested event or call setCustomPasscode.
In the next section we will look at one example of a workflow we can use to gather a PIN style passcode from the user.
A PIN Entry Workflow
One type of workflow we can use is a PIN entry workflow. With this workflow, the user will use a Personal Identification Number consisting of four to nine digits to lock and unlock the vault.
When creating a new PIN:
- The user enters a PIN and taps the "Enter" button.
- The user is asked to enter the PIN again to verify.
- The user enters a PIN and taps the "Enter" button.
- If the PINs do not match an error is displayed.
- If the PINs match the modal is closed, passing back the PIN that was entered.
- The calling code passes the PIN to the vault so it can be used to generate a key to lock the vault.
The user cannot cancel the creation of a PIN, they must complete the operation.
When unlocking the vault:
- The user enters a PIN and taps the "Enter" button.
- The modal is closed, passing back the PIN that was entered.
- The calling code passes the PIN to the vault so it can be used to generate a key to unlock the vault.
The user can cancel the PIN entry. If the user cancels, the modal is closed without any data being passed back.
To accomplish this, we will create a PIN Entry Component that encapsulates the user interaction required to enter a PIN. This dialog is displayed in a modal when the vault requests a passcode.
Create a PIN Entry Component
The PIN entry component is a numeric keypad that handles the PIN entry flows for both PIN creation and for unlocking the vault. The full code can be found in our GitHub demo repository. We walk through the key points below.
Cancel and Submit buttons.
Do not allow the user to cancel if they are creating a passcode.
A user feedback area so they know what is going on.
The keypad.
We need to update the PIN value when the user presses a number button or the delete button on the keypad.
We do not want to display the PIN, so we calculate a string of asterisks instead.
There are three modes. The user is either creating a PIN, verifying the newly created PIN, or entering a PIN to unlock the vault.
When the modal opens, the user is either creating a PIN or entering a PIN to unlock the vault.
When the user taps the Enter button, we need to handle the proper flow.
When creating a PIN, either move on to "verify" mode, display an error if the PIN failed in "verify" mode, or close the modal returning the PIN.
When entering a PIN to unlock the vault, close the modal returning the entered PIN.
The component needs a little styling to make it all look nice.
Cancel and Submit buttons.
Do not allow the user to cancel if they are creating a passcode.
A user feedback area so they know what is going on.
The keypad.
We need to update the PIN value when the user presses a number button or the delete button on the keypad.
We do not want to display the PIN, so we calculate a string of asterisks instead.
There are three modes. The user is either creating a PIN, verifying the newly created PIN, or entering a PIN to unlock the vault.
When the modal opens, the user is either creating a PIN or entering a PIN to unlock the vault.
When the user taps the Enter button, we need to handle the proper flow.
When creating a PIN, either move on to "verify" mode, display an error if the PIN failed in "verify" mode, or close the modal returning the PIN.
When entering a PIN to unlock the vault, close the modal returning the entered PIN.
The component needs a little styling to make it all look nice.
Hook Up the Modal
When the vault needs a PIN it will call onPasscodeRequested()
, passing a Boolean flag indicating if the passcode is
being used to set a new passcode (true
) or unlock the vault (false
). We use this callback function to display the
PIN Entry Component in a modal dialog, await a response from it, and pass that response back to the vault.
Import the modal controller and the PIN dialog component.
Inject the modal controller.
Create and present the modal.
Set the passcode for the vault based on the data sent back from the PIN dialog.
Import the modal controller and the PIN dialog component.
Inject the modal controller.
Create and present the modal.
Set the passcode for the vault based on the data sent back from the PIN dialog.
At this point, we can test the Custom Passcode workflows via the "Use Custom Passcode" button.
Advanced Implementations
The Custom Passcode is very flexible, and you do not have to use the basic PIN Entry implementation we have outlined here. We do not have demos for these, but would be happy to assist you in your implementation if needed.
Here are a few ideas for other implementations.
Custom Passcode Entry
We created a PIN Entry component here. We could have created any sort of component we wanted so long as that component generates a unique key based on user interaction. Here are some other ideas:
- Ask the user to provide a passphrase.
- Ask the user to enter a pattern on a grid.
- Ask the user to select a combination of pictures or colors.
- Use a voice recognition to ask the user for a secret word (accuracy of the voice recognition will obviously be very important).
The input mechanism is up to you so long as it results in a string that can be used to generate a key.
Using with a Device
Vault
The suggested configuration for a Device
vault is to use DeviceSecurityType.Both
to allow Biometrics to be used with
a System Passcode backup. You can, however, use Custom Passcode as a backup mechanism. To do this, you will need two vaults,
a Device
vault using DeviceSecurityType.Biometrics
(Biometrics-only) and a CustomPasscode
vault.
The CustomPasscode
vault is the source of truth for the authentication session information.
The Device
vault stores the passcode for the CustomPasscode
vault.
When unlocking the application, the following workflow is used:
- User uses Biometrics to unlock the
Device
vault. - The Passcode is obtained from the unlocked
Device
vault. - The stored Passcode is used to unlock the
CustomPasscode
vault to obtain the session information.
In cases where the user fails to unlock the Device
, the application can use the CustomPasscode
vault directly, asking
the user to enter the passcode in order to unlock the vault.
Best Practices
Favor Device
Vaults
While CustomPasscode
vaults are secure, a Device
vault is able to take full advantage of the device's hardware-based
encryption and secure storage mechanisms. For this reason, Device
vaults should be favored on devices that support them.
For the most secure applications, the following types of vaults are suggested:
- Use a
Device
type vault withDeviceSecurityType.Both
. If the user does not have Biometrics configured, this configuration will fall back to using the System Passcode. - Use an
InMemory
vault if a user has neither Biometrics nor a System Passcode configured on their device.
With this configuration, users who have secured their devices properly will be able to utilize their device security to remain logged in to your application. For users who have not properly secured their devices, your application will still be secure since users will need to provide their application credentials every time the application is locked or launched.
Favor System Passcode Backup
Using a Custom Passcode as backup for Biometrics has the following disadvantages:
- It is non-standard. The standard fallback for Biometrics failing when unlocking the device itself, for example, is to use the System Passcode. As such, that is what the user will expect.
- Using the System Passcode is built in to Identity Vault. As such, it requires far less code in your application.
- Using the System Passcode takes full advantage of the device's encryption hardware area.
As such, while using a Custom Passcode is secure, using a System Passcode as the fallback mechanism for failing Biometrics maximizes both security and usability while minimizing complexity within your application.