Keychain empty when backup restored on new phone (works if phone stays the same)

I'm working on a Swift App that stores Passwords of type kSecClassGenericPassword

I'm using the Swift wrapper provided in the Apple Documentation (KeychainPasswordItem.swift).


I want stored keychain values to be availabe, after a backup of a device is restored on another device via iCloud Backup

When I restore the backup on the same device everything just works fine. But when I do it on a new device the keychain ist just empty.


I've enabled Keychain Sharing in the Project's capabilities.

I've also set kSecAttrSynchronizable to kCFBooleanTrue and kSecAttrAccessible to kSecAttrAccessibleAfterFirstUnlock.


None of it seems to Work. I don't use kSecAttrAccessGroup because I don't want to share the keychain with another app.

Any ideas what I am doing wrong?


    private static func keychainQuery(withService service: String, account: String? = nil, accessGroup: String? = nil) -> [String : AnyObject] {
        var query = [String : AnyObject]()
        query[kSecClass as String] = kSecClassGenericPassword
        query[kSecAttrService as String] = service as AnyObject?
        query[kSecAttrSynchronizable as String] = kCFBooleanTrue
        query[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock

        if let account = account {
            query[kSecAttrAccount as String] = account as AnyObject?
        }

        if let accessGroup = accessGroup {
            query[kSecAttrAccessGroup as String] = accessGroup as AnyObject?
        }
        
        return query
    }



FInally found out that this behaviour is completely normal yet very unintuitive.


iCloud Backup behaves just like an unencrypted iTunes Backup.

Keychain is only recovered when backup is restored on the same device it was made on.

kSecAttrAccessible has no impact on the backup behaviour.

Keychain empty when backup restored on new phone (works if phone stays the same)
 
 
Q