iCloud sync keychain

爱⌒轻易说出口 提交于 2019-12-01 16:36:21

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.

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.

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;
    }
    

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

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