Sonntag, 7. Dezember 2014

Why passwords should not be stored on a mobile device



Apps for mobile devices, like tablets and smartphones replace more and more the traditional desktops and notebooks for internet-based services. For a solid number of apps in the various App Stores it is nearly every time mandatory for the users to authenticate against the App (for using the services the App provides). This often raises the question how to store the username and the password on the device securely. The easy answer to this is: unfortunately not possible. A Keychain to store sensitive data securely has been offered by iOS since version 2.0 and by Android since version 4.0, but you should keep in mind that it is still possible to read all those values stored there.


The problem:

Since the Keychain on Android was established in version 4.0 and apps often have to support older versions, the only possibility is to use the integrated AccountManager or the Shared Preferences folder, which every app has included. On iOS you can use the Keychain without hesitation. It is also possible to save informations within the app folder structure (preferences files or SQLite database).

The Keychain on both systems has a prevention against unauthorized access, but both systems are Linux/Unix-based and they share a user who has access to everything: root. By using a root exploit it is possible to read all stored secrets on a mobile device. Since Android is suffering from a complicated update policy it is much easier to achieve this: regarding the current statistics [1] still 9.6% of Android devices are using the old versions Froyo and Gingerbead (2.2 - 2.3.7). 33.9% are using KitKat (4.4) and the newest version Lollipop (5.0) isn't even mentioned. Especially the devices with Gingerbead and Froyo won't get any new updates to fix security vulnerabilities. On iOS it is often argued that there are no root expoits, but the Jailbreak community has found one for every single version and has published it. Currently team TaiG has found one for the newest iOS version 8.1.1. For iOS 8.0 team Pangu published it and for iOS 7 it was the Evasi0n team. A root exploit for iOS is sold on the black market for 500.000$ to 1.000.000$ [2]. Public authorities like the NSA are willing to pay such an amount. Nevertheless, this does not necessarily mean that there are no exploits if they aren't publicly available.


Let's have a quick look at the Keychains:


The Keychain file itself (keychain-2.db) is protected with the device key, which can be obtained through jailbreaking / root exploit. Every entry is encrypted with the passcode key. When unlocked the users passcode is encrypted many times using a modified PBKDF2 (Password-Based Key Derivation Function 2) algortihm (AES with the UID key) to generate the passcode key. This key is hold in memory till the device is locked. A lot of users are using just a 4 digits pin which makes it easy to brute-force (average time is about 15 minutes). Hopefully this get's better with the new Touch ID feature, introduced with the iPhone 5S.




Each Keychain Entry is encrypted with the 128-bit AES master key in CBC mode. The master key is a 128-bit key created by reading from /dev/urandom. It is encrypted with a hash of the users lockscreen password created with the PBKDF2 function from the SSL library (till Android version 4.3.x). Since Android 4.4 (KitKat) the PBKDF2 key derivation function (KDF) is replaced with scrypt [3].


The solution:

The question for an app developer now is: How can you make sure that the customers can use the app with all features without storing the password on the device? The solution: a token-based approach like OAuth 2.0 [4]. During the first start-up of my app, the customer has to provide his username and  password once. Afterwards, the app receives a token from the server which is going to be used as authentication. This token can be stored encrypted in the Keychain. The advantage of this  approach is that if an invader gets access to the device or records the token via a Man-in- the-Middle attack, he only receives a restrictive token which is only usable for certain use-cases (like viewing only some content, synchronising contacts and so on). He won't receive the password for an email account or maybe a bank account and so on. Tokens also have the advantage that they can be  revoked and only are valid for a certain time.


tl;dr
Currently there is no practical way to store a password safely on a mobile device. Only the token-based approach is helpful here.


Links:
[1] http://developer.android.com/about/dashboards/index.html
[2] http://grahamcluley.com/2013/07/zero-day-ios-exploit/
[3] https://www.tarsnap.com/scrypt.html
[4] http://oauth.net/2/