iOS Security: Protecting the iOS Keychain
Most mobile applications must interact with Web services that require authentication. Services usually require authentication to provide personalized content (such as social networks) or to limit access to sensitive information (such as corporate data). Most commonly, the authentication requires a username and a password. Most iOS apps store these credentials in the Keychain — a password management system provided by Apple for iPhone and iPad apps to securely store small pieces of sensitive information such as usernames, passwords, tokens, certificates, private keys for asymmetric encryption, and secret keys for symmetric encryption.
This article will present the information necessary for companies to protect access to their corporate resources when those credentials are stored in the iOS Keychain, and for security-conscious individuals to protect their personal passwords stored in the Keychain.
There are a number of conditions that impact the security of the data an app stores in the Keychain:
- the presence and strength of a passcode on the device
- the access restrictions assigned to the app’s Keychain items
- whether the device is jailbroken
- the chipset used in the device
Each of these conditions and its impact on the security of data stored in the Keychain is explored below.
All of built-in data protection mechanisms on the iPhone, iPad, and iPod touch require the user to set a passcode.
That point is so important it is worth restating for emphasis: without a passcode, all data on the device — including sensitive data stored in the Keychain — can be read by anyone with momentary access to the device.
A passcode can be a numeric PIN or a complex password with letters, numbers, symbols, and foreign characters. The passcode is used as an input to generate the encryption keys used to protect the device’s data, including the Keychain. Without a passcode, the entire content of the Keychain can be read by anyone with physical access to the device.
(To enable data protection, open the Settings app, select the Passcode or Touch ID & Passcode menu item and tap the Turn Passcode On button.)
Prior to iOS 8, there was no Apple-sanctioned way to determine if a passcode had been set on the device, so apps had no way of knowing if the data they entrusted to the Keychain was actually secure. Starting with iOS 8, Apple provided a new
kSecAttrAccessible value that allows apps to store items in the Keychain only when the device has a passcode:
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Additionally, if the user removes her passcode, all the Keychain items with this access restriction will be removed as well, preventing the items from being exposed on the unprotected device.
If the app’s data entrusted to the Keychain only needs to remain secret against casual inspection (“oops, I left my phone in a cab…”), the presence of a passcode and the use of the
WhenPasscodeSet restriction may be sufficient.
However, if the app’s Keychain must be protected from a more deliberate attack, it is critical that the passcode be hard to guess. Commercial forensic solutions, such as Cellebrite UFED Touch, provide “passcode recovery” tools that will brute-force 4-digit PINs in 20-30 minutes on a standard PC. When a device is protected by a complex, alpha-numeric password, the tools provide an easy-to-use interface for performing a dictionary attack. If the passcode is not resistant to such attacks, then the attacker will be able to de-crypt the Keychain and gain access to the app’s passwords and keys stored within it.
(To enable complex passwords on your device, open the Settings app, select the Passcode or Touch ID & Passcode menu item, and disable the Simple Passcode option.)
Unfortunately, there is no Apple-sanctioned way for an app to determine the complexity of its device’s passcode. However, devices under control of a mobile device manager (“MDM”) can have configuration profiles installed that require passcodes to meet certain rules, such as minimum length.
It is worth noting that Touch ID does not change the strength of the device’s passcode — it only makes it easier to enter. A device using a 4-digit PIN as its passcode is not made more secure by enabling Touch ID. However, the presence of Touch ID encourages use of stronger passcodes, since it removes most of the inconvenience related to entering those passcodes.
Keychain Access Restrictions
Starting with iOS 4, each item in the Keychain can have its own access restriction defining when the item can be accessed — the item is securely encrypted the rest of the time (assuming a strong passcode has been set for the device). The options are detailed below, from least-restrictive to most-restrictive. The first three options have variants ending with
ThisDeviceOnly that prevent the Keychain item from being included in iTunes backups, iCloud backups, or iCloud Keychain. The
ThisDeviceOnly variant is commonly used by corporate apps that must protect corporate data, while the standard values are commonly used by apps available through the App Store to give the user control of her data and enable easy device migration.
kSecAttrAccessibleAlways: The data in the Keychain item will not be stored securely. The data can always be accessed regardless of whether the device is locked. Apple recommends that apps no longer use this access restriction — the next one should be used instead.
kSecAttrAccessibleAfterFirstUnlock: The Keychain item is secure while the device is off, and when the device has been turned on (or restarted) before the passcode is first entered. After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications, such as for background fetching.
kSecAttrAccessibleWhenUnlocked: The Keychain item is secure when the device is off and when it is locked. This is recommended for items that need to be accessible only while the application is in the foreground. It can also be used for items that need to be accessed for background fetching if it is acceptable that the fetch can only be performed when the device is unlocked; for example, when the user is checking her email or Twitter stream. This is the default value for modern versions of iOS.
kSecAttrAccessibleWhenUnlocked, but only available if a passcode is set on the device. If the device lacks a passcode, the item will not be stored. Disabling the passcode after the item has been created with this restriction causes the item to be deleted. Items with this attribute never migrate to a new device through backups or iCloud. This access restriction is only available in iOS 8.0 and later.
The Keychain’s contents are not secure on a jailbroken device. When a device is jailbroken, the sandbox that limits each app to its own Keychain items can be circumvented, so any code executed on the device while the device is unlocked can access all Keychain items for all apps.
Generally, consumer apps available in the App Store do not care if the user has jailbroken her device since she has deliberately made her data vulnerable. However, corporate apps are usually responsible for protecting corporate data and services, so jailbroken devices are a concern.
For some apps, it may be sufficient to detect if the device has been jailbroken whenever the app is launched. If the device is jailbroken, the app can respond appropriately; for example, by deleting all its Keychain items and data files. Prateek Gianchandani and Trustwave have good introductions to detecting if an app is executing on a jailbroken device.
Unfortunately, no jailbreak detection method is completely reliable. Additionally, the detection routine can only run when the app is launched or receives background calls to its app delegate. If the user jailbreaks her device after the app has stored sensitive information in the Keychain, then the information will be vulnerable until the next time the app runs.
If it is unacceptable for the app’s sensitive data to be exposed this way, then the app must roll its own security and force the user to provide an app-specific password when needed. Implementing such a solution is beyond the scope of this article, but Chapter 10 (“Implementing Encryption”) in Jonathan Zdziarski’s Hacking and Securing iOS Applications provides a solid introduction to the topic.
Modern Device Hardware
Devices running iOS 7 or iOS 8 on the Apple A7 and later A-series processors leverage Apple’s new “Secure Enclave” technology. The Secure Enclave is a coprocessor that performs security-sensitive tasks — such as verifying the user’s passcode and encrypting/decrypting keychain content — without interference from malicious programs.
In practical terms, devices with a Secure Enclave cannot be jailbroken without the user’s consent; i.e., while the device is locked or powered off. This significantly impedes attackers attempting to gain access to sensitive data by jailbreaking such a device. However, it does not prevent a user willingly jailbreaking her own device.
This makes the Keychain much more secure in environments that have external consequences to discourage users from jailbreaking, such as company policies for corporate-owned and “BYOD” devices.
Additionally, the Secure Enclave enforces a 5-second delay between failed attempts to unlock the device. This provides a governor against brute-force attacks in addition to safeguards enforced by iOS.
This article explored several of the factors that can improve or reduce the security of data stored in the iOS Keychain. Each application must make its own trade-offs regarding the level of security required to protect its Keychain items, balancing the user’s management of her credentials against the possible need to protect third-party or corporate data.
For apps that must protect third-party or corporate data, the iOS Keychain can provide adequate security when all of the following conditions are met:
- the sensitive items are stored with an access restriction that makes them only available when the device is unlocked
- the device has a strong passcode
- the device has an Apple A7 and later A-series processor
- there exists a real-world monitoring and response mechanism that discourages the user from jailbreaking the device