{"id":21835,"date":"2015-10-19T11:21:27","date_gmt":"2015-10-19T18:21:27","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=21835"},"modified":"2015-10-19T11:21:27","modified_gmt":"2015-10-19T18:21:27","slug":"easily-authenticate-users-with-androids-confirm-credential","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/easily-authenticate-users-with-androids-confirm-credential\/","title":{"rendered":"Easily Authenticate Users with Android&#8217;s Confirm Credential"},"content":{"rendered":"<p>\t\t\t\tThere are a number of ways to authenticate users on mobile devices, from traditional passwords and pins to new biometric fingerprint sensors. Most users are already using one of the most secure mobile authentication implementations, the device lock screen. With Android Marshmallow and the new Confirm Credential API, it&#8217;s now possible to utilize the lock screen to detect when the user last unlocked their device and even re-prompt them to confirm their identity without having to remember yet another app-specific password. All authentication is securely stored in a crypto key from the Android KeyStore with a customizable timeout period that&#8217;s carried across multiple applications.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/confirm-980x576.jpg\" alt=\"confirm-980x576\" width=\"980\" height=\"576\" class=\"aligncenter size-full wp-image-21837\" \/><\/p>\n<h2>Getting Started<\/h2>\n<p>It&#8217;s important to note that your user must have his or her lock screen already secured in Android&#8217;s settings before it&#8217;s possible to use the Confirm Credential API. Most Android users will have already done this, but it&#8217;s possible to check before even attempting by getting access to the KeyguardManager and prompting users to secure their lock screen:<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/Create private KeyguardManager that will be used later on for Confirm Credentials\nKeyguardManager keyguardManager;\n\nprotected override void OnCreate(Bundle bundle)\n{\n  \/\/...Activity creation\n  keyguardManager = (KeyguardManager)GetSystemService(Context.KeyguardService);\n  if (!keyguardManager.IsKeyguardSecure)\n  {\n    \/\/ Show a message that the user hasn't set up a lock screen.\n    Toast.MakeText(this, \"Secure lock screen isn't set up.\\n\"\n                    + \"Go to 'Settings -&gt; Security -&gt; Screen lock' to set up a lock screen\",\n                    ToastLength.Short).Show();\n  }\n  else\n  {\n    \/\/We are free to create our Cyrpto Key\n    CreateKey();\n  }\n}\n<\/pre>\n<h2>Creating Crypto Key<\/h2>\n<p>Once it&#8217;s verified that the user has set up a secure lock screen, it&#8217;s possible to attempt to create a crypto key with a specified timeout policy that&#8217;s used to see when the user last logged in. This timeout is set for a number of seconds, and developers are free to set it to any amount necessary for the app.<\/p>\n<pre class=\"lang:csharp decode:true\">\nconst string KeyName = \"my_special_key\";\nvoid CreateKey()\n{\n  \/\/ Generate a key to decrypt payment credentials, tokens, etc.\n  \/\/ This will most likely be a registration step for the user when they are setting up your app.\n  var keyStore = KeyStore.GetInstance(\"AndroidKeyStore\");\n  keyStore.Load(null);\n  var keyGenerator = KeyGenerator.GetInstance(KeyProperties.KeyAlgorithmAes, \"AndroidKeyStore\");\n\n  \/\/ Set the alias of the entry in Android KeyStore where the key will appear\n  \/\/ and the constrains (purposes) in the constructor of the Builder\n  keyGenerator.Init(new KeyGenParameterSpec.Builder(KeyName, KeyStorePurpose.Decrypt | KeyStorePurpose.Encrypt)\n\t\t\t\t\t   .SetBlockModes(KeyProperties.BlockModeCbc)\n\t\t\t\t\t   .SetUserAuthenticationRequired(true)\n                                           \/\/ Require that the user has unlocked in the last 30 seconds\n\t\t\t\t\t   .SetUserAuthenticationValidityDurationSeconds(30)\n\t\t\t\t\t   .SetEncryptionPaddings(KeyProperties.EncryptionPaddingPkcs7)\n\t\t\t\t\t   .Build());\n  keyGenerator.GenerateKey();\n}\n<\/pre>\n<h2>Testing Last Unlock<\/h2>\n<p>When your code needs to authenticate the user, it simply needs to attempt to encrypt any data with the key that was created earlier. If the data can be encrypted with the key, then the user has logged in within our timeout period. If not, an <i>UserNotAuthenticatedException<\/i> is thrown and it&#8217;s time to confirm credentials. Here&#8217;s how to test encrypting a bit of data.<\/p>\n<pre class=\"lang:csharp decode:true\">\nstatic readonly byte[] SecretData = new byte[] { 1, 2, 3, 4, 5, 6 };\nvoid TryEncrypt()\n{\n  try\n  {\n    var keyStore = KeyStore.GetInstance(\"AndroidKeyStore\");\n    keyStore.Load(null);\n    var secretKey = keyStore.GetKey(KeyName, null);\n    var cipher = Cipher.GetInstance(KeyProperties.KeyAlgorithmAes + \"\/\" + KeyProperties.BlockModeCbc + \"\/\"  + KeyProperties.EncryptionPaddingPkcs7);\n    cipher.Init(CipherMode.EncryptMode, secretKey);\n    \/\/attempt encrypting data\n    cipher.DoFinal(SecretData);\n    \/\/ If the user has recently authenticated, you will reach here.\n  }\n  catch (UserNotAuthenticatedException)\n  {\n    \/\/ User is not authenticated, let's authenticate with device credentials.\n    ShowAuthenticationScreen();\n  }\n}\n<\/pre>\n<h2>Showing the Authentication Screen<\/h2>\n<p>If the user is already authenticated, the app can move on to a checkout screen or log the user in. Otherwise, it&#8217;s time to prompt the user to confirm their credentials by simply creating a new Confirm Device Credential Intent from the KeyguardManager.  <\/p>\n<pre class=\"lang:csharp decode:true\">\nstatic readonly int ConfirmRequestId = 1;\nvoid ShowAuthenticationScreen()\n{\n  var intent = keyguardManager.CreateConfirmDeviceCredentialIntent((string)null, (string)null);\n  if (intent != null)\n  {\n    StartActivityForResult(intent, ConfirmRequestId);\n  }\n}\n<\/pre>\n<p>Android will automatically launch the lock screen that the user has specified when the Confirm Credential Intent is activated, whether it be a pin, password, or any other type of security such as a fingerprint. Personally I use a pin on my devices, so here&#8217;s what it looks like on my Nexus 9 when the intent is launched:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screenshot_20151006-110449_framed.png\" alt=\"Pin Screen\" width=\"600\" height=\"826\" class=\"aligncenter size-full wp-image-21851\" \/><\/p>\n<p>At this point the user can do one of two things: <\/p>\n<ul>\n<li>Enter the correct credentials.<\/li>\n<li>Cancel the unlock screen.<\/li>\n<\/ul>\n<p>The Activity will get a callback with a return code when one of these occur, which can be checked if the correct credentials were entered.<\/p>\n<pre class=\"lang:csharp decode:true\">\nprotected override void OnActivityResult(int requestCode, Result resultCode, Intent data)\n{\n  if (requestCode == ConfirmRequestId)\n  {\n    \/\/ Credentials entered successfully!\n    if (resultCode == Result.Ok)\n    {\n      ShowPurchaseConfirmation();\n    }\n    else\n    {\n      \/\/ The user canceled or didn\u2019t complete the lock screen\n      \/\/ operation. Go to error\/cancellation flow.\n    }\n  }\n}\n<\/pre>\n<p>There you have it! No more passwords to remember, completely customized timeouts, and a workflow that&#8217;s familiar to your users.<\/p>\n<h2>Learn More<\/h2>\n<p>To learn more about getting started with Android Marshmallow, be sure to read through the <a href=\"https:\/\/developer.xamarin.com\/guides\/android\/platform_features\/introduction-to-marshmallow\/\">getting started documentation<\/a>. You can also find this sample and other Android Marshmallow samples on our <a href=\"https:\/\/github.com\/xamarin\/monodroid-samples\/tree\/master\/android-m\">Sample Gallery<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are a number of ways to authenticate users on mobile devices, from traditional passwords and pins to new biometric fingerprint sensors. Most users are already using one of the most secure mobile authentication implementations, the device lock screen. With Android Marshmallow and the new Confirm Credential API, it&#8217;s now possible to utilize the lock [&hellip;]<\/p>\n","protected":false},"author":544,"featured_media":21851,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[5],"class_list":["post-21835","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-android"],"acf":[],"blog_post_summary":"<p>There are a number of ways to authenticate users on mobile devices, from traditional passwords and pins to new biometric fingerprint sensors. Most users are already using one of the most secure mobile authentication implementations, the device lock screen. With Android Marshmallow and the new Confirm Credential API, it&#8217;s now possible to utilize the lock [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/21835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/544"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=21835"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/21835\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=21835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=21835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=21835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}