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.
Currently
there is no practical way to store a password safely on a mobile device.
Only the token-based approach is helpful here.
[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/