2012-07-15 139 views
7

在我的应用程序中,我希望能够同步由用户创建的配置。我想使用iCloud同步该配置,以便在所有设备上始终保持相同。但是,我使用钥匙串来存储密码。iCloud同步钥匙扣

有没有办法同步钥匙串数据?

回答

3

不,钥匙串同步不是iCloud的一部分。它是点mac同步的一部分,但不再可用。

可能会有关于这是否是个好主意的反馈(自动将密码从一台设备移到另一台设备),特别是在多人共享一个iCloud帐户的情况下(可能,但现在不能保证)。

如果您觉得将密码存储在设备的钥匙串中(并且因此要求用户每个设备至少输入一次),那么您将需要提供自己的加密和安全性,并将数据直接存储在iCloud中,如在密钥库中。

16

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

+0

#jrc你能帮我在keychain中设置kSecAttrSynchronizable属性吗? – iKT 2015-06-24 09:53:54

2

这些是我为钥匙串制作的实用方法。 kSecAttrSynchronizable是使iCloud Sync工作的原因。希望他们帮助。

  • 钥匙串查询。
  • 删除项目
  • 删除项目
  • 保存项目
  • 将项目

    + (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; 
    } 
    
+0

+1为完整答案,提供全部代码需要归档数据。 (id)数据对象当然必须符合协议。 – loretoparisi 2015-10-14 08:59:22