2012-07-15 16 views
7

En mi aplicación, quiero ser capaz de sincronizar una configuración que el usuario crea. Quería usar iCloud para sincronizar esa configuración para que siempre sea la misma en todos los dispositivos. Pero, uso el llavero para almacenar la contraseña.iCloud sync keychain

¿Hay alguna forma de sincronizar también los datos de llavero?

Respuesta

3

No, la sincronización de llavero no forma parte de iCloud. Era parte de la sincronización de dot mac, pero eso ya no está disponible.

Probablemente haya comentarios sobre si esta es una buena idea o no (mover contraseñas automáticamente de un dispositivo a otro), especialmente en situaciones en las que varias personas comparten una cuenta de iCloud (probable, pero no garantizada actualmente).

Si cree que almacenar la contraseña en el llavero del dispositivo (y por lo tanto requiere que el usuario ingrese al menos una vez por dispositivo), tendrá que proporcionar su propio cifrado y seguridad, y almacenar los datos en iCloud directamente. como en el almacén de claves.

16

iCloud Keychain es una nueva característica en iOS 7.0.3 y OS X Mavericks 10.9. Especifique el atributo kSecAttrSynchronizable al agregar un elemento de llavero utilizando la API SecItem.

+0

#jrc ¿Puede ayudarme a establecer el atributo kSecAttrSynchronizable en el llavero? – iKT

2

Estos son los métodos de utilidad que he hecho para llavero. kSecAttrSynchronizable es lo que hace que iCloud Sync funcione. Espero que ayuden

  • Llaveros Query.
  • Quitar elemento
  • elemento Borrar
  • Guardar elemento
  • elemento de carga

    + (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 para la respuesta completa y el código que proporciona todo es necesario para archivar datos. Por supuesto, el objeto de datos (id) debe cumplir el protocolo . – loretoparisi