iCloud同步钥匙串

10
在我的应用程序中,我想要同步用户创建的配置。我希望使用iCloud来同步该配置,以便在所有设备上始终保持相同。但是,我使用钥匙串存储密码。
有没有办法也同步钥匙串数据?
4个回答

19

iCloud钥匙串是iOS 7.0.3和OS X Mavericks 10.9中的新功能。在使用SecItem API添加钥匙串项时,需要指定kSecAttrSynchronizable属性。


#jrc 你能帮我设置钥匙串中的kSecAttrSynchronizable属性吗? - Kirti Nikam

5

以下是我为钥匙串制作的实用方法。kSecAttrSynchronizable 是使 iCloud 同步工作的关键。希望它们有所帮助。

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

完整答案和提供所有需要存档数据的代码都将得到+1分。当然,(id)数据对象必须符合<NSCoding>协议。 - loretoparisi

3
不,钥匙串同步不是iCloud的一部分。它是dot mac同步的一部分,但现在不再提供该服务。
可能会有反馈,关于是否自动将密码从一个设备移动到另一个设备是个好注意(尤其是在多人共享iCloud帐户的情况下),这是可能的,但不是保证的。
如果您认为将密码存储在设备的钥匙串中(因此要求用户至少每个设备输入一次),那么您需要提供自己的加密和安全性,然后直接将数据存储在iCloud中,例如在密钥库中。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接