{"id":20630,"date":"2015-08-26T15:07:10","date_gmt":"2015-08-26T22:07:10","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=20630"},"modified":"2015-08-26T15:07:10","modified_gmt":"2015-08-26T22:07:10","slug":"securing-your-app-with-touch-id","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/securing-your-app-with-touch-id\/","title":{"rendered":"Securing Your App with Touch ID"},"content":{"rendered":"<p>\t\t\t\tOne of my favorite features of the iPhone is Touch ID, introduced by Apple with the release of the iPhone 5s a couple of years ago. <img decoding=\"async\" class=\"alignright size-full wp-image-20649\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/touch-id-icon.png\" alt=\"touch-id-icon\" width=\"100\" height=\"100\" \/>Touch ID adds biometric authentication to your device so users can touch the home button to unlock their device instead of using a pin code.<\/p>\n<p>Since its initial release, Apple has added a few new ways to use Touch ID, including integrating it as an essential part of Apple Pay and adding an API for developers to use Touch ID in their apps. In this blog post we&#8217;re going to discuss how you can leverage Touch ID to create secure user authentication. We&#8217;ll include a fallback to store the password in Keychain and authenticate our users against that in cases where the device doesn\u2019t support Touch ID.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screen-Shot-2015-08-17-at-16.55.22.png\"><img decoding=\"async\" class=\"aligncenter wp-image-20634 size-large\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screen-Shot-2015-08-17-at-16.55.22-1024x642.png\" alt=\"Xamarin Studio with TouchID Design\" width=\"1024\" height=\"642\" \/><\/a><\/p>\n<h2>Supporting Older Devices<\/h2>\n<h3>Sign Up<\/h3>\n<p>If the device has Touch ID, we won&#8217;t need to sign the user up since the device can authenticate them for us. But to ensure we support devices such as iPhone 4, 4S, and the iPhone 5, we&#8217;ll want to ensure we&#8217;ve got a fallback in place. To do this, we&#8217;ll use Keychain to store and validate the user credentials.<\/p>\n<p>I like to use UserDefaults for storing usernames to read back information when the app launches and populate the username UITextField for the user. It&#8217;s small touches like this that make an app feel more polished and help achieve higher ratings on the app store.<\/p>\n<pre class=\"lang:csharp decode:true\">\nvar hasLoginKey = NSUserDefaults.StandardUserDefaults.BoolForKey(&quot;hasLogin&quot;);\u2028\nif (!hasLoginKey)\u2028\n    NSUserDefaults.StandardUserDefaults.SetValueForKey(new NSString(tbxUsername.Text), new NSString(&quot;username&quot;));\u2028\n<\/pre>\n<h3>Saving the Password<\/h3>\n<p>It&#8217;s important to note that we don&#8217;t want to use UserDefaults here since it&#8217;s not a secure approach to saving your data. Instead, we&#8217;ll use Keychain, which is iOS&#8217;s built-in secure storage service that allows us to store passwords, keys, certificates, and more. My colleague <a href=\"https:\/\/github.com\/Krumelur\">Ren\u00e9 Ruppert<\/a> has developed a helpful wrapper for storing passwords on iOS with Keychain that you can grab <a href=\"https:\/\/github.com\/Krumelur\/iOSPasswordStorage\/blob\/master\/KeychainHelpers.cs\">here<\/a> and is what I&#8217;ll be using.<\/p>\n<p>To save the password, we simply call \u2018SetPasswordForUsername\u2019. In this case, I have my serviceId set to \u2018MySecureApp\u2019.<\/p>\n<pre class=\"lang:csharp decode:true\">\nHelpers.KeychainHelpers.SetPasswordForUsername(tbxUsername.Text, tbxPassword.Text, serviceId, Security.SecAccessible.Always, true);\n<\/pre>\n<p>Once we&#8217;ve done that, it&#8217;s time to set \u2018hasLogin\u2019 to true and synchronize the UserDefaults.<\/p>\n<pre class=\"lang:csharp decode:true\">\nNSUserDefaults.StandardUserDefaults.SetBool(true, &quot;hasLogin&quot;);\u2028\nNSUserDefaults.StandardUserDefaults.Synchronize();\n<\/pre>\n<h3>Validating the User Credentials<\/h3>\n<p>We&#8217;re now ready to validate the credentials provided by the user. To do this, we get the password from the Keychain and check that it matches the password provided. We then repeat the process with the username. If CheckLogin returns true, then we can continue loading new views.<\/p>\n<pre class=\"lang:csharp decode:true\">\nstatic bool CheckLogin(string username, string password)\n{\n    if (password == Helpers.KeychainHelpers.GetPasswordForUsername(username, serviceId, true) &amp;&amp;\n        username == NSUserDefaults.StandardUserDefaults.ValueForKey(new NSString(&quot;username&quot;)).ToString())\n    {\n        return true;\n    }\n\n    return false;\n}\n<\/pre>\n<h2>Adding Touch ID<\/h2>\n<p>Implementing user authentication with Touch ID is painless and only involves a tiny amount of code since iOS does most of the heavy lifting for us. Below is all the code required to get started.<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/Lets double check the device supports Touch ID\nif (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out error))\n{\n    var replyHandler = new LAContextReplyHandler((success, error) =&gt;\n        {\n            InvokeOnMainThread(() =&gt;\n                {\n                    if (success)\n                    {\n                        var newVC = new UIViewController();\n                        PresentViewController(newVC, true, null);\n                    }\n                    else\n                    {\n                        var alert = new UIAlertView(&quot;OOPS!&quot;, &quot;Something went wrong.&quot;, null, &quot;Oops&quot;, null);\n                        alert.Show();\n                    }\n                });\n        });\n    context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, &quot;Logging in with Touch ID&quot;, replyHandler);\n}\nelse\n{\n    var alert = new UIAlertView(&quot;Error&quot;, &quot;TouchID not available&quot;, null, &quot;BOOO!&quot;, null);\n    alert.Show();\n}\n<\/pre>\n<h2>Wrapping Up<\/h2>\n<p>Not all apps require a backend service for user authentication, and iOS provides lots of options for authenticating locally. If you wanted to take this one step further you could look at integrating <a href=\"https:\/\/agilebits.com\/onepassword\">1Password<\/a> authentication into your app. I&#8217;ve created a completed version of the demo project on <a href=\"https:\/\/github.com\/MikeCodesDotNet\/SecureMyApp\">GitHub<\/a>, to which I&#8217;ll be adding 1Password support to in a separate branch that you can find <a href=\"https:\/\/github.com\/MikeCodesDotNet\/SecureMyApp\/tree\/1Password\">here<\/a>. Additionally, be sure to read through our <a href=\"https:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_touchid\/\" title=\"Touch ID Documentation\">full documentation<\/a> on integrating Touch ID.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of my favorite features of the iPhone is Touch ID, introduced by Apple with the release of the iPhone 5s a couple of years ago. Touch ID adds biometric authentication to your device so users can touch the home button to unlock their device instead of using a pin code. Since its initial release, [&hellip;]<\/p>\n","protected":false},"author":1929,"featured_media":21130,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6,4],"class_list":["post-20630","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>One of my favorite features of the iPhone is Touch ID, introduced by Apple with the release of the iPhone 5s a couple of years ago. Touch ID adds biometric authentication to your device so users can touch the home button to unlock their device instead of using a pin code. Since its initial release, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/20630","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\/1929"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=20630"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/20630\/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=20630"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=20630"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=20630"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}