iOS Keychain Migration and Data Protection - Part 1

I have posted in the past on how to access the keychain to securely store and retrieve data from within an iOS app. However the recent press attention on iOS location data being stored in iTunes backups has got me to take a closer look at how data is secured when it is moved off the device.

Encrypted Backups

When you connect an iOS device (iPhone, iPod touch, iPad) to a computer to sync with an iTunes library a backup of the data on the device is also made. The backup includes application settings and data but excludes things like the tmp and Caches folder (see this Apple support article for the full list of what is included). The backup also includes the keychain so that account passwords, WiFi passwords or any other data you choose to save in the keychain is stored. iTunes allows you to specify that the backup should be encrypted in which case a password is required to restore the backup to a device.

Keychain Migration

You may decide that it is not worth the effort of encrypting the backup data especially since it is questionable how secure the backup really is. However even if you are not worried about the security of the backup there is a really good reason why you might want to encrypt the backup.

An unencrypted backup can only be restored the original device that it was taken from. This means that if you buy a new device you will have to enter keychain data such as account settings and passwords manually. An encrypted backup can be restored to a different device avoiding a whole load of pain. The only requirement is that you remember the password as you will be asked for it when you attempt the restore.

This ability to migrate keychain data between devices was introduced in iOS 4 but I think has been overlooked somewhat both by users and application developers. In fact the keychain services allow the application developer a fine degree of control on how data is handled when it is backed up.

Data Protection

As well as providing a means to migrate keychain data iOS 4 also introduced a more sophisticated level of data protection for data stored on the device itself. The iPhone 3GS introduced hardware based encryption of data on the device but it seems that is what not too difficult to circumvent. Things have hopefully been improved with iOS 4:

  • The user entered passcode is now used to protect the hardware encryption keys providing an additional layer of protection.
  • The application developer can specify when encrypted data should be available (e.g. only when the device is unlocked).
  • Keychain data can be set as migratable or non-migratable preventing it from being restored to a new device if required.
  • Separate encryption keys are used to encrypt the keychain data and the device filesystem

To enable data protection you need to set a passcode for the device (Settings > General > Passcode) once you do that you should see a confirmation that data protection is enabled at the bottom of the Passcode Lock settings screen:

As it would happen there have been some reports this week that the iOS 4 hardware encryption has been cracked though this looks like it involves a brute force attack on the user passcode. By default the passcode is a simple 4 digit pin code giving only 10,000 combinations which it is claimed can be broken in under 40 minutes on an iPhone 4. To defeat this attack you can set a stronger passcode by turing off the Simple Passcode option in the settings screen. You can then enter a longer and stronger alphanumeric passcode. You can also set the device to erase all data after 10 failed passcode attempts to be extra sure.

Data Protection Classes

The keychain services provide API access to add, update, search and delete items from the keychain. Refer back to my post on simple keychain access for the full details and example code. What I want to cover here are the additional data protection classes that can be used to control the availability of the data stored in the keychain. Basically you can choose between three classes of availability for keychain data:

  • Unlocked: data can only be accessed when the device is unlocked (which of course may require the user to enter the passcode).
  • After first unlock: data can be accessed when the device is locked provided it has been unlocked at least once since the device was started.
  • Always: the data is accessible always even when the device is locked

For backward compatibility the default is “always” though Apple recommends that you use the most protective class possible. This is generally “unlocked” unless you have an application that needs to access keychain data when running in the background (the user might lock the device whilst your app is running cutting off its access to the keychain). In the situation where you might need to access the keychain of a locked device you should use the “after first unlock” class.

If you are hanging onto data that you have retrieved from the keychain then you also need to ensure you purge this data when the user locks the device. Apple provides application delegate methods and notifications to make it easy for you to do this. Your application has about 10 seconds to clean up before the keychain service is locked. Attempting to access it after that point will generate an error until the device is unlocked again.

As well as being able to set the availability of the keychain data you can also control how it is handled when the keychain is migrated to a new device. Remember if the user has an encrypted backup they can restore the keychain contents to a different device. By default all data added to the keychain is set as migratable. If you want the data to only be available on the current device you must set it to be non-migratable.

Apple actually defines six data protection classes consisting of migratable and non-migratable versions of the three data availability classes. If you do nothing the keychain defaults to the most open option so data will be available always and migratable.

Where is the Code?

This is becoming a long post so I will follow up with some example code in a separate post. In the meantime if you want to dig into some more detail on how data encryption works on iOS I recommend taking a look at Session 209 - Securing Application Data from WWDC 2010.