For an Android app managing cryptographic keys, I want to ensure that the device has had a screen lock set up continuously since the first time the app has been run.
Specifically, the app will only allow using the keys if the device has a secure look configured (which can be checked via KeyguardManager.isDeviceSecure()). But if the user disables their screen lock, someone else could potentially pick it up, re-enable the screen lock and continue to use the app pretending to be the original user. I want to prevent this, but still not require user authentication for every use of the keys (which rules out using Android KeyStore user authentication enforcement)
I currently see two ways to delete the data if the screen lock is disabled, both of which have downsides:
- Set up a DeviceAdminReceiver and listen for screen lock changes with onPasswordChanged, invalidating keys if the screen lock is disabled. This is problematic since it requires
USES_POLICY_LIMIT_PASSWORD
, which will no longer be supported in API level 29. - Create a "canary" KeyStore key with user authentication enforcement and check whether it throws a KeyPermanentlyInvalidatedException when used. This solution feels very hacky, depends on implementation details (e.g. KeyPermanentlyInvalidatedException being thrown before UserNotAuthenticatedException) and is not event-based in the way solution 1 is, which means that the keys will not be deleted immediately after the screen lock is disabled.
Is there a better way to act upon the deactivation of the device screen lock?