2011-08-22 13 views
21

Me gustaría saber si hay una manera de restablecer el llavero de Mi aplicación. Me pregunto si hay algo que existe comoRestablecer Llavero de la aplicación de iPhone

[NSUserDefaults resetStandardUserDefaults]

para llavero. La cadena de claves no se restablece incluso después de eliminar la aplicación. Hasta ahora, la única forma que conozco es restablecerlos uno por uno desde la aplicación.

+0

@ serge-k, esa pregunta se hizo en 2012, mientras que esta fue en 2011. –

+0

Es cierto, simplemente figura la otra respuesta que se encuentra aquí http://stackoverflow.com/questions/14086085/how-to-delete-all -keychain-items-accessible-to-a-app es una solución más actualizada. Puedo dejarlo como un enlace, eliminé la bandera duplicada. –

Respuesta

52

Como todas las respuestas hasta el momento se basa en que ya conoce los identificadores que desea borrar Me gustaría presentar la siguiente solución que elimina todas las claves existentes para la aplicación (iOS solamente)

-(void)resetKeychain { 
    [self deleteAllKeysForSecClass:kSecClassGenericPassword]; 
    [self deleteAllKeysForSecClass:kSecClassInternetPassword]; 
    [self deleteAllKeysForSecClass:kSecClassCertificate]; 
    [self deleteAllKeysForSecClass:kSecClassKey]; 
    [self deleteAllKeysForSecClass:kSecClassIdentity]; 
} 

-(void)deleteAllKeysForSecClass:(CFTypeRef)secClass { 
    NSMutableDictionary* dict = [NSMutableDictionary dictionary]; 
    [dict setObject:(__bridge id)secClass forKey:(__bridge id)kSecClass]; 
    OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict); 
    NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%ld)", result); 
} 

Swift 2,2 versión:

func resetKeychain() { 
    self.deleteAllKeysForSecClass(kSecClassGenericPassword) 
    self.deleteAllKeysForSecClass(kSecClassInternetPassword) 
    self.deleteAllKeysForSecClass(kSecClassCertificate) 
    self.deleteAllKeysForSecClass(kSecClassKey) 
    self.deleteAllKeysForSecClass(kSecClassIdentity) 
} 

func deleteAllKeysForSecClass(secClass: CFTypeRef) { 
    let dict: [NSString : AnyObject] = [kSecClass : secClass] 
    let result = SecItemDelete(dict) 
    assert(result == noErr || result == errSecItemNotFound, "Error deleting keychain data (\(result))") 
} 

Swift versión 3

func resetKeychain() { 
    deleteAllKeysForSecClass(kSecClassGenericPassword) 
    deleteAllKeysForSecClass(kSecClassInternetPassword) 
    deleteAllKeysForSecClass(kSecClassCertificate) 
    deleteAllKeysForSecClass(kSecClassKey) 
    deleteAllKeysForSecClass(kSecClassIdentity) 
} 

func deleteAllKeysForSecClass(_ secClass: CFTypeRef) { 
    let dict: [NSString : Any] = [kSecClass : secClass] 
    let result = SecItemDelete(dict as CFDictionary) 
    assert(result == noErr || result == errSecItemNotFound, "Error deleting keychain data (\(result))") 
} 
+4

¿hay alguna manera de eliminar todos los llaveros manualmente usando el teléfono mismo? algo así como las instrucciones [aquí] (http://www.imore.com/how-access-and-view-your-icloud-keychain-passwords-ios-7) – abbood

+2

@abbood programmatically que debería ser imposible. ¿Por qué? Debido a que su aplicación está en la zona de pruebas y nunca podrá eliminar todos los elementos de llavero ** de otras aplicaciones **. El único escenario posible para 'adivinar * * sería usar el simulador en sí mismo' iOS Simulator -> Restablecer contenido y configuración ' – Honey

-5
- (void)resetKeychainItem 
{ 
    OSStatus junk = noErr; 
    if (!keychainItemData) { 
     self.keychainItemData = [[NSMutableDictionary alloc] init]; 
    } else if (keychainItemData){ 
     NSMutableDictionary *tempDictionary = [self dictionaryToSecItemFormat:keychainItemData]; 
     junk = SecItemDelete((CFDictionaryRef)tempDictionary); 
     if (junk != noErr) { 
      UIAlertView *dialog = [[UIAlertView alloc] initWithTitle:@"Keychain Error" message:[NSString stringWithFormat:@"A problem with updating the secure Keychain items with this information (likely, this email address information is duplicated in another Player). Error code: %d %@", junk, [self resultText:-junk]] delegate:self cancelButtonTitle:NSLocalizedStringFromTable(@"Ok", @"Localizable", @"display text") otherButtonTitles:nil]; 
      [dialog show]; 
      [dialog release]; 
      //NSAssert(junk == noErr || junk == errSecItemNotFound, @"Problem deleting current dictionary."); 
      return; 
     } 
    } 

    // Default attributes for keychain item. 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrAccount]; 
    [keychainItemData setObject:@"" forKey:(id)kSecValueData]; 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrLabel]; 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrDescription]; 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrComment]; 
    // Default data for keychain item. 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrModificationDate]; 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrService]; 


} 
+0

¿Puede agregar algunos comentarios para ayudar a los usuarios a comprender lo que hace su código –

+0

@JimP, podría darnos un poco de explicación. usted todavía necesita proporcionar todas las claves para restablecer ¿verdad? Tengo mucha información segura y quiero restablecerlos a todos, existe una necesidad. –

+4

¡Qué mala respuesta ... – Chris

11
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"nameOfYourKeychain" accessGroup:nil]; 

[keychainItem resetKeychainItem]; 

Mucho más simple :)

Editar: En respuesta a una pregunta formulada por debajo de - lo que es KeychainItemWrapper?

Es una clase escrito por Apple que se puede descargar aquí: http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html

añadirlo a su proyecto y luego importarlo en la que desea utilizarlo. Luego use el fragmento de código que proporcioné arriba.

+2

Hola, ¿qué es KeychainItemWrapper? – hzxu

+0

@hzxu actualizó la respuesta, gracias. – jcrowson

+1

Gracias, pero si necesito tener varios pares clave-valor, y no puedo usar un diccionario para todas mis cosas y almacenarlo en una clave estándar como 'kSecValueData' porque el valor debe ser una cadena, entonces necesito crear como muchos 'KeychainItemWrapper' como el número de mis pares clave-valor? – hzxu

2

versión basada en bloques de solución @ Vegard:

void (^deleteAllKeysForSecClass)(CFTypeRef) = ^(CFTypeRef secClass) { 
    id dict = @{(__bridge id)kSecClass: (__bridge id)secClass}; 
    OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict); 
    NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%d)", (int)result); 
}; 
deleteAllKeysForSecClass(kSecClassGenericPassword); 
deleteAllKeysForSecClass(kSecClassInternetPassword); 
deleteAllKeysForSecClass(kSecClassCertificate); 
deleteAllKeysForSecClass(kSecClassKey); 
deleteAllKeysForSecClass(kSecClassIdentity); 

Para aquellos de nosotros que les gusta simplemente introduce el código en sin necesidad de tener métodos de ayuda.

+0

Gracias por esto. También es la implementación más simple y más expresiva. –

Cuestiones relacionadas