iCloud sync keychain

爱⌒轻易说出口 提交于 2019-12-04 03:07:56

问题


In my app, I want to be able to sync a configuration that gets created by the user. I wanted to use iCloud to sync that configuration so that it is always the same on all devices. But, I use the keychain to store the password.

Is there a way to also sync keychain data?


回答1:


No, keychain syncing is not part of iCloud. It was part of dot mac syncing, but that is no longer available.

There will probably be feedback on whether this is a good idea or not (automatically moving passwords from one device to another), especially in the situation where multiple people share an iCloud account (likely, but not guaranteed these days).

If you feel that storing the password on the device's keychain (and thus requiring the user to enter it at least once per device), then you will need to provide your own encryption and safety and store the data in iCloud directly, such as in the keystore.




回答2:


iCloud Keychain is a new feature in iOS 7.0.3 and OS X Mavericks 10.9. Specify the kSecAttrSynchronizable attribute when adding a keychain item using the SecItem API.




回答3:


These are the utility methods I've made for keychain. kSecAttrSynchronizable is what makes iCloud Sync work. Hope they help.

  • Keychain Query.
  • Remove item
  • Delete item
  • Save item
  • Load item

    + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
        return [NSMutableDictionary dictionaryWithObjectsAndKeys:
                (__bridge id)kSecClassGenericPassword, (__bridge id)kSecClass,
                service, (__bridge id)kSecAttrService,
                service, (__bridge id)kSecAttrAccount,
                service, (__bridge id)kSecAttrSynchronizable,
                (__bridge id)kSecAttrAccessibleAfterFirstUnlock, (__bridge id)kSecAttrAccessible,
                nil];
    }
    
    + (void)save:(NSString *)service data:(id)data {
        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
        SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
        [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
        SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
    }
    
    + (void)remove:(NSString *)service {
         NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
         SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
    }
    
    +(NSString *)keychainItem:(NSString *)service{
        id data = [self load:service];
    
        if([data isKindOfClass:[NSString class]]){
            return data;
        }
        return @"";
    }
    
    + (id)load:(NSString *)service {
        id ret = nil;
        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
        [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
        [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
        CFDataRef keyData = NULL;
        if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
            @try {
                ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
            }
            @catch (NSException *e) {
                NSLog(@"Unarchive of %@ failed: %@", service, e);
             }
            @finally {}
        }
        if (keyData) CFRelease(keyData);
        return ret;
    }
    



回答4:


Looking to do the same, haven't tried yet but this looks helpful: https://github.com/iosengineer/BMCredentials



来源:https://stackoverflow.com/questions/11489864/icloud-sync-keychain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!