10

I have a use case that requires the user to confirm device credential, and the createConfirmDeviceCredentialIntent method in KeyguardManager perfectly meets my need. However, this method was added since API 21.(reference link) So how can I achieve the same functionality before Android 5.0? I also want to support versions like Android 4.X.

Thanks!

Danny Zhang
  • 109
  • 5

2 Answers2

5

Before 21 level this is certainly not possible on non-rooted device and there is no alternative with regular permissions.

If it is ok to require extra admin permissions, it is probably possible to emulate credential confirmation very loosely, with much more effort, by implementing DeviceAdminReceiver.onPasswordSucceeded. Lock the screen, when password succeeded perform the required action. This may turn out to be relatively complex because the action is not always received (only if status has changed), need to keep last success, communicate with receiver, etc.

As a side note, double check the use case and your design, in most cases when createConfirmDeviceCredentialIntent is used it is actually not required and other design choices may eliminate the need for it.

It was better to provide details of what exactly you are trying to protect. If it is a scenario for accidental access to the device by an unauthorized person and a permanent token is generated, say, from some oauth service, it may be reasonable either to reauthorize through the same service login flow or to store some hmac of original credentials along with token then prompt and re-validate credentials instead of prompting for device credentials. Alternatively, if that is enough for use case, you can use google login to authorize access to your app/token and verify google user is the same for the stored token.

Community
  • 1
  • 1
Fedor Losev
  • 3,244
  • 15
  • 13
1

The best answer I have seen for this situation is described in a blog post:

Android Secrets

However, it recreates system classes that are private and calls AOSP code that is not public. My bounty is for a better answer that would not require explicit Class naming inside the project. Perhaps Smart Lock or another awesome security library can be used for the backward compatibility I require.

Tim
  • 4,790
  • 4
  • 33
  • 41
Beth Mezias
  • 270
  • 3
  • 13
  • The problem there seems no way to force pin confirmation with these private APIs. It is unblocked once on phone unlock, so you just get the secure store without protection challenge on opened phone. If your purpose is just that, you are trying to answer a different question, it differs from what was asked as this is not a replacement for createConfirmDeviceCredentialIntent confirmation. – Fedor Losev Dec 19 '16 at 23:46
  • But it is... The pin confirmation UI is in the blog post is on a dangerous path using Android system: `try { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { startActivity(new Intent("android.credentials.UNLOCK")); } else { startActivity(new Intent("com.android.credentials.UNLOCK")); } } catch (ActivityNotFoundException e) { Log.e(TAG, "No UNLOCK activity: " + e.getMessage(), e); }` Bounty is on to get a more legit backward compatible library for local authentication? Is there any other way to go other than sending my user back to my server to type. – Beth Mezias Dec 21 '16 at 15:50
  • Not just it is a dangerous path (well, not *so* dangerous), it does not work in the way one may think. Once store is unlocked (including on phone unlock) it will not prompt for pin anymore, sending UNLOCK intent will popup nothing and AFAIK there is no way to force auth to popup this way. So the answer to the original question - there is no replacement (so yours question is different). – Fedor Losev Dec 21 '16 at 16:19
  • Any way for protecting token before use without device confirmation will require some custom information from user, because you can't use device confirmation (except the lock workaround I've outlined). If you don't want to take the lock path in my answer, it is better to let user type original login instead of using some additional custom information. But you don't have to go back to server to validate it. – Fedor Losev Dec 21 '16 at 16:20
  • Since you mention Google login -> the app supports diverse authorities and account types. Those servers are, for all intents and purposes, read-only resources. To simplify the login process a token type String must be encrypted and protected. Certain authorities could require some form of authentication with each new session and will cooperate with our servers if our app sets up a local pattern/pin/password/print check. That's the questions. How to do that local check. – Beth Mezias Dec 29 '16 at 06:18