Overview
The Futurae Android SDK uses the Android Keystore system to securely manage cryptographic keys. On devices that support it, the SDK may leverage hardware-backed security modules, such as Android StrongBox, for additional protection.
On some Android devices, especially those with heavily customized OS layers like Samsung One UI or Huawei EMUI, the Android Keystore system may behave unpredictably. When hardware-backed security is involved, this can lead to corrupted key material, repeated initialization errors, forced account re-enrollment, or even application freezes (ANRs).
To handle these situations, the SDK provides four main options:
-
Skip hardware security: configure the SDK with
setSkipHardwareSecurity(true)to avoid hardware-backed storage (like StrongBox) and fall back to the hardware-backed Trusted Execution Environment (TEE) if supported by the device.
-
Switch SDK configuration: after corruption or repeated errors, update an existing installation to use
setSkipHardwareSecurity(true)without forcing user re-enrollment.
-
Account recovery: if initialization fails with corruption errors, attempt to recover SDK secrets using
launchAccountRecovery(...), provided essential cryptographic material is still available.
- Reset SDK: If recovery or reconfiguration is not possible, resetting the SDK and re-enrolling affected user’s account is the last resort. After resetting the SDK, it’s recommended to disable hardware security before initializing the SDK, as this might prevent further Keystore related errors.
Each option is described in detail below, with guidance on when to use it, how it works, and what to expect.
Skip Hardware Security
What is it?
Hardware-backed Keystore modules like StrongBox provide additional protection by isolating cryptographic keys in dedicated secure hardware. This works reliably on most devices, but some manufacturers' implementations are unstable and can cause errors.
By setting setSkipHardwareSecurity(true) the SDK sets isStrongBoxBacked = false, preventing the use of StrongBox (SECURITY_LEVEL_STRONGBOX) while still allowing the Keystore to select the next highest available security level. Therefore, if the device supports hardware-backed security (TEE), the Keystore will still use that protection rather than falling back to a purely software-based implementation.
- Enabled (true): StrongBox is skipped. Keys are stored in the TEE if the device supports it, or in the software-based Android Keystore otherwise.
- Disabled (false, default): the SDK will attempt to use StrongBox if available on the device.
When to use it
Enable setSkipHardwareSecurity(true) if you encounter:
-
FTKeystoreExceptionor its subclasses (FTKeyNotFoundException,FTSignatureException, etc.)
- Users on devices known for unstable StrongBox implementations
- Repeated keystore-related crashes during account setup
How it works
We recommend initializing the SDK with setSkipHardwareSecurity(true) :
SDKConfiguration config = new SDKConfiguration.Builder()
.setSkipHardwareSecurity(true)
// other config...
.build();
FuturaeSDK.launch(application, config)
What to expect
- Improves stability on affected devices
- Does not eliminate all keystore errors, but reduces their frequency significantly
See SDK Initialization Errors & Recovery for potential errors during SDK initialization.
Switch SDK Configuration
What is it?
The SDK provides a way to switch to a different SDK configuration post initialization. If errors keep recurring, you can change the SDK configuration such as changing setSkipHardwareSecurity(false) to setSkipHardwareSecurity(true) post-initialization using Switch SDK configuration. This lets you migrate from hardware-backed to software-backed security without data loss or user re-enrollment.
If the SDK cannot be recovered or reconfigured, the fallback is to reset() and re-enroll.
When to use it
- After corruption or repeated keystore errors
- When you need to move an existing installation to
setSkipHardwareSecurity(true)
How it works
- Launch with the original configuration
- Update the configuration using
switchToLockConfiguration(), settingsetSkipHardwareSecurity(true)
- On the next and subsequent launches, initialize with the new config
What to expect
- Reconfiguration with skip hardware reduces the chance of repeated failures
- Existing keys and encrypted data remain intact, so users do not need to re-enroll
See Switch SDK configuration docs for implementation details.
Account Recovery: Recovering from Keystore Errors
What is it?
Account Recovery is a built-in SDK mechanism that attempts to repair a corrupted state without requiring the user to re-enroll. When cryptographic material or encrypted storage is damaged (FTCorruptedStateException, including its subclass FTEncryptedStorageCorruptedException), you can call launchAccountRecovery(...) to try to restore functionality.
This exception contains three critical pieces of information:
- isRecoverable (Boolean): Indicates if the SDK installation can be recovered via Account Recovery.
- message (String): Details regarding the corruption.
- cause (Throwable): The underlying error that triggered the state.
When to use it
You should trigger the recovery flow when you catch an FTCorruptedStateException during FuturaeSDK.launch(...)or within an onError callback, provided that isRecoverable is true.
How it works
Before attempting recovery, you must check the state of the exception. The logic follows this pattern:
- Inspect the isRecoverable attribute.
- If true, call
launchAccountRecovery(...)using the appropriate user-presence mode (Biometrics, Device Credentials, or SDK PIN). - If false, the cryptographic material is irrecoverable. You must call
FuturaeSDK.reset()and inform the user that re-enrollment is required.
For code samples covering each lock configuration type, see the SDK documentation on recovery.
For a clean implementation, refer to the SDKRecoveryFlow pattern in the Futurae Sample App, which is the main composable informing the user about the corrupted state and the result (success or failure) of the recovery attempt.
What to expect
- Success: The SDK repairs the internal state and resumes normal operation.
- Failure: If recovery fails or the 5-attempt limit is reached, you must proceed to reset.
-
Irrecoverable State: If isRecoverable is false,
launchAccountRecovery(...)cannot be used to restore the account. In this scenario performing, a SDK reset and re-enrolling the user is the only path forward.
See SDK Initialization Errors & Recovery for details and implementation example.
Reset for Non-Recoverable Errors
What is it?
Reset completely clears the SDK state. All keys, secrets, and enrollments are removed. Users will need to re-enroll their accounts.
When to use it
- If
launchAccountRecovery(...)fails or you have exceeded the 5 recovery attempt limit
- If reconfiguration is not possible (SDK is stuck in corrupted state)
- As the last resort to restore a clean state
How it works
- Reset the SDK (
FuturaeSDK.reset())
- Re-enroll the user
- Re-launch the SDK using
setSkipHardwareSecurity(true)to reduce the chance of future problems
What to expect
- Complete data wipe
- Users will need to re-enroll
- Ensures a clean slate, but with the cost of user disruption
Case Study: Recovering Biometrics via SDK PIN Fallback
In some instances, hardware-backed Keystore corruption doesn't cause a total SDK crash, but specifically "breaks" the biometric authentication path. Below is a real-world scenario observed on certain devices and how to resolve it without data loss.
Observed Behaviour
-
Successful Start: The user launches the app (
FuturaeSDK.launchsucceeds). - Initial Enrollment: The user enrolls an account and successfully enables biometrics.
-
Biometric Failure: At a later point, biometric unlock consistently fails or stops responding, with the
unlock()method throwing anFTKeystoreOperationException.
Resolution Path
If your application uses Lock Type SDK PIN with Biometrics Optional, you can recover the biometric functionality by following these steps:
-
Re-enable biometrics: call
deactivateBiometricsandactivateBiometricsin order to regenerate the biometric key that is failing during unlock. - Fallback to PIN: Prompt the user to authenticate using their SDK PIN instead of biometrics.
-
Switch Configuration: Once the user is authenticated via PIN, trigger the switch SDK configuration:
-
switchToLockConfiguration(). - Set
setSkipHardwareSecurity(true).
-
- Restore Biometrics: After the configuration has switched to software-based security, the biometric authentication path should be re-initialized. Because the SDK is no longer struggling with the unstable hardware-backed StrongBox, biometric authentication should function normally again.
⚠️ This specific recovery flow is only applicable if the SDK is configured with Lock Configuration Type through the method setLockConfigurationType() to SDK_PIN_WITH_BIOMETRICS_OPTIONAL. If biometrics are the exclusive lock type and the keys are corrupted, you must proceed to Account Recovery or Reset.
Frequently Asked Questions
1. What exactly causes biometric login to fail, when PIN login and data encryption still work?
The three cases rely on the Keystore differently, which is why they fail independently:
- Biometric login keys tied to biometrics are more sensitive and error-prone compared to e.g. AES data encryption keys. EC keys (especially tied to biometrics) are more affected by OS/firmware updates
- PIN login never goes through that verification step, so it's unaffected.
- App-level data encryption keys (used to encrypt locally stored data) are also stored in the Keystore, but they aren't tied to user authentication and are less affected by OS/firmware updates.
In short: it's not that StrongBox itself is broken in general, it's that the specific cross-chip verification flow biometrics relies on is where certain manufacturers' implementations become unreliable.
2. If it fails once, is it recoverable, or is it permanent for that device?
Deactivating and reactivating biometrics may or may not fix the issue, depending on the root cause. If the problem is a corrupted key, reactivation generates a fresh key and can resolve it. However, if the underlying issue is that the device cannot generate the necessary keys at all (e.g. a broken StrongBox environment), reactivation probably won't help, the new key will likely hit the same broken path and fail again.
- Rebooting the device, or re-enrolling the fingerprint/face in Android system settings, can sometimes clear the faulty state temporarily — but these aren't reliable long-term fixes, and the issue tends to resurface.
- The only reliable fix is to move the affected installation off StrongBox entirely:
- Reset the SDK's data.
- Re-initialize the SDK with
setSkipHardwareSecurity(true). - Re-activate the user's accounts.
- This creates fresh keys in the standard hardware-backed secure storage (TEE), if the device supports hardware-backed secure storage, instead of StrongBox, which avoids the unstable code path. If your Lock Configuration is
SDK_PIN_WITH_BIOMETRICS_OPTIONAL, you can achieve the same result without a full reset — see the Case Study above for the PIN-authenticatedswitchToLockConfiguration()path.
3. Why does this affect one device of a given model (e.g. a specific Xiaomi Ultra 15) but not an identical unit?
This usually comes down to low-level differences that aren't visible as a user-facing setting:
- Firmware/patch-level variance: two otherwise-identical phones can be running different monthly security patches or regional firmware builds, and the bug may only be present in one of them.
- Transient faults: a device's secure storage can enter a bad state on a specific handset (often persisting until the next reboot), independent of the model or OS version.
It is not something a user or admin can diagnose or fix via device settings, which is why setSkipHardwareSecurity(true) exists at the app level to bypass this device-specific fragmentation entirely rather than relying on per-device workarounds.
4. Is Futurae working on a fix for the underlying issue?
The root cause lives in device manufacturers' StrongBox firmware, which is outside Futurae's control, there is no fix Futurae can ship for the OEM firmware itself. Our engineering effort is focused on making the workaround as reliable as possible:
-
setSkipHardwareSecurity(true)bypasses the unstable StrongBox implementations and significantly reduces the related issues. - Initializing the SDK on a background thread mitigates ANRs, whereas main-thread initialization provides greater Keystore stability.
- We continue to monitor keystore-related edge cases and refine SDK handling as new patterns are reported.
5. Does setSkipHardwareSecurity(true) disable hardware-backed security entirely, or only StrongBox specifically?
It only disables StrongBox, it does not disable hardware-backed security in general.
Setting setSkipHardwareSecurity(true) sets isStrongBoxBacked = false, which prevents the Keystore from selecting SECURITY_LEVEL_STRONGBOX. The Keystore then selects the next highest available security level. On the large majority of modern devices, this means keys are still created in the TEE (Trusted Execution Environment), a hardware-isolated environment, just one tier below StrongBox, rather than falling back to a purely software-based keystore.
A purely software-backed fallback only happens on a device with no hardware-backed Keystore at all, which is rare among modern Android devices.
For security teams evaluating this flag, the key difference is where the security protection comes from. StrongBox uses a dedicated, tamper-resistant hardware component, while the TEE uses an isolated security environment built into the device’s main chip. Both are hardware-backed. So, setSkipHardwareSecurity(true) switches from StrongBox to the TEE, it does not switch from hardware security to software security.
6. Is there any advice besides using setSkipHardwareSecurity(true)?
setSkipHardwareSecurity(true) remains the primary and most effective mitigation, since it addresses the root cause directly and there isn't a real alternative that does the same. A few complementary practices help reduce impact further:
- Initialize on a background thread: reduces UI-thread blocking and the chance of ANRs when StrongBox firmware is slow to respond or times out.
- Keep PIN available as a fallback: ensures users on affected devices always have a working authentication path, even before any reconfiguration is applied.
- Stay on the latest SDK version: you'll automatically benefit from ongoing stability improvements and keystore edge-case handling.
Need help?
For any technical support, do not hesitate to contact support@futurae.com.
Comments
0 comments
Article is closed for comments.