1

I'm implementing refresh token storage in a mobile app and trying to understand the practical security differences between these two approaches:

Option 1: Hardware-backed storage WITHOUT biometric requirement

  • iOS: Keychain with kSecAttrAccessibleWhenUnlockedThisDeviceOnly
  • Android: Android Keystore with setUserAuthenticationRequired(false)

Option 2: Hardware-backed storage WITH biometric requirement

  • iOS: Keychain with SecAccessControlCreateWithFlags using .biometryCurrentSet
  • Android: Android Keystore with setUserAuthenticationRequired(true)

My understanding is that both options store the token encrypted by hardware (Secure Enclave/TEE), but Option 1 allows retrieval once the device is unlocked, while Option 2 requires biometric authentication for each access.

My specific question: On a non-rooted/non-jailbroken device, with a signed, non-debug app what additional attack vectors does Option 1 expose that Option 2 prevents?

For example, if an attacker has physical access to an unlocked device can they extract tokens from Option 1 using ADB or similar tools?

1 Answer 1

4

In android, setUserAuthenticationRequired(true) adds another layer of security by providing system back authentication of the user within the app. So, even if the screen is unlocked, the attacker will not be able to access the sensitive components of the app on which the in-app authentication is applied.

The app must declare the types of authentication that it wants to support. It supports biometric and additionally as a fallback, it allows device credential also.

If your app only supports setUnlockedDeviceRequired, then your data will become available whenever the app will run given that the screen has been unlocked at least once since the last reboot.

ADB cannot access internal data of apps. You need an exploit. If the kernel is compromised after the device is taken from you in unlocked state, in-app data encryption keys which are secured by setUserAuthenticationRequired cannot be extracted. This is because system back in-app authenticaion is cryptographically bound to the key material in the keystore. But it can dump in-app data encryption keys which are secured by setUnlockedDeviceRequired when the screen is unlocked.

setUnlockedDeviceRequired(true) is related to but distinct from setUserAuthenticationRequired(true). setUnlockedDeviceRequired(true) requires that the device be unlocked, whereas setUserAuthenticationRequired(true) requires that a specific type of strong authentication has happened within a specific time period within the app. They may be used together or separately; there are cases in which one requirement can be satisfied but not the other.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.