Secure keychain syncing
When a user enables iCloud Keychain for the first time, the device establishes a circle of trust and creates a syncing identity for itself. The syncing identity consists of a private key and a public key, and is stored in the device’s keychain. The public key of the syncing identity is put in the circle, and the circle is signed twice: first by the private key of the syncing identity, and then again with an asymmetric elliptical key (using P-256) derived from the user’s iCloud account password. Also stored with the circle are the parameters (random salt and iterations) used to create the key that’s based on the user’s iCloud password.
For two-factor authentication accounts, an additional similar syncing circle is created and stored in CloudKit. Device identities in this system consist of two pairs of asymmetric elliptical keys (using P-384), also stored in the keychain. Each device maintains its own list of identities it trusts, and signs this list using one of its identity keys.
iCloud storage of the syncing circle
The signed syncing circle is stored in the user’s iCloud key-value storage area. It can’t be read without knowing the user’s iCloud password and is unable to be validly modified without having the private key of the syncing identity of its member.
For two-factor authentication accounts, each device’s syncing list is stored in CloudKit. The lists can’t be read without knowing the user’s iCloud password, and they can’t be modified without having the private keys of the owning device.
How a user’s other devices are added to the syncing circle
When new devices sign in to iCloud, they join the iCloud Keychain syncing circle in one of two ways: either by pairing with and being sponsored by an existing iCloud Keychain device, or by using iCloud Keychain recovery.
During the pairing flows, the applicant device creates new syncing identities for both the syncing circle and the syncing lists (for two-factor authentication accounts) and presents them to the sponsor. The sponsor adds the public key of the new member to the syncing circle and signs it again with both its syncing identity and the key derived from the user’s iCloud password. The new syncing circle is placed in iCloud, where it’s similarly signed by the new member of the circle. In two-factor authentication accounts, the sponsor device also provides the joining device with a voucher signed by its identity keys, showing that the applicant device should be trusted. It then updates its individual list of trusted syncing identities to include the applicant.
There are now two members of the signing circle and each member has the public key of its peer. They now begin to exchange individual keychain items through iCloud key-value storage, or they store them in CloudKit, whichever is most appropriate for the situation. If both circle members have updates to the same item, one or the other is chosen, resulting in eventual consistency. Each item that’s synced is encrypted so that it can be decrypted only by a device within the user’s circle of trust; it can’t be decrypted by any other devices nor by Apple.
As new devices join the syncing circle, this “join process” is repeated. For example, when a third device joins, it can be paired with either of the existing devices. As new peers are added, each peer syncs with the new one. This is designed to ensure that all members have the same keychain items.
Only certain items are synced
Some keychain items are device specific, such as iMessage keys, and so must stay on the device. As a result, every item that will sync must be explicitly marked with the
Apple sets this attribute for Safari user data (including usernames, passwords and credit card numbers) as well as for Wi-Fi passwords, HomeKit encryption keys and other keychain items supporting end-to-end iCloud encryption.
Additionally, by default, keychain items added by third-party apps don’t sync. Developers must set the
kSecAttrSynchronizable attribute when adding items to the keychain.