2008-10-10 18 views

Respuesta

34

Hay un llavero puede utilizar - para el código, la mejor apuesta es de revisar la aplicación de la muestra GenericKeychain de Apple:

GenericKeychain sample

+1

Gracias por señalarlo! – maralbjo

5

También recuerde que cuando se genera un AppID, si quieres más de una aplicación para acceder a la misma información de llavero, debe generar un comodín AppID (#####. com.prefix. *) ...

44

Otra cosa a tener en cuenta: las API de llavero no trabaje en el simulador cuando use versiones anteriores (2.x, 3.x) del iPhone SDK. ¡Esto podría ahorrarle mucha frustración cuando realice las pruebas!

+0

Esto ha sido arreglado por un tiempo ahora. Funciona para mí en el simulador. – bartvdpoel

+0

Sí, ahora funciona en el sim. Creo que se corrigió en una versión 3.x. –

8

Esto es lo que uso para almacenar los pares clave/valor en el llavero. Asegúrese de añadir a su proyecto Security.framework

#import <Security/Security.h> 

// ------------------------------------------------------------------------- 
-(NSString *)getSecureValueForKey:(NSString *)key { 
    /* 

    Return a value from the keychain 

    */ 

    // Retrieve a value from the keychain 
    NSDictionary *result; 
    NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecReturnAttributes, nil] autorelease]; 
    NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, kCFBooleanTrue, nil] autorelease]; 
    NSDictionary *query = [[NSDictionary alloc] initWithObjects: objects forKeys: keys]; 

    // Check if the value was found 
    OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, (CFTypeRef *) &result); 
    [query release]; 
    if (status != noErr) { 
     // Value not found 
     return nil; 
    } else { 
     // Value was found so return it 
     NSString *value = (NSString *) [result objectForKey: (NSString *) kSecAttrGeneric]; 
     return value; 
    } 
} 




// ------------------------------------------------------------------------- 
-(bool)storeSecureValue:(NSString *)value forKey:(NSString *)key { 
    /* 

    Store a value in the keychain 

    */ 

    // Get the existing value for the key 
    NSString *existingValue = [self getSecureValueForKey:key]; 

    // Check if a value already exists for this key 
    OSStatus status; 
    if (existingValue) { 
     // Value already exists, so update it 
     NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, nil] autorelease]; 
     NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, nil] autorelease]; 
     NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease]; 
     status = SecItemUpdate((CFDictionaryRef) query, (CFDictionaryRef) [NSDictionary dictionaryWithObject:value forKey: (NSString *) kSecAttrGeneric]); 
    } else { 
     // Value does not exist, so add it 
     NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecAttrGeneric, nil] autorelease]; 
     NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, value, nil] autorelease]; 
     NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease]; 
     status = SecItemAdd((CFDictionaryRef) query, NULL); 
    } 

    // Check if the value was stored 
    if (status != noErr) { 
     // Value was not stored 
     return false; 
    } else { 
     // Value was stored 
     return true; 
    } 
} 

Vale la pena señalar que estos valores clave/no se eliminan si el usuario elimina su aplicación. Si un usuario borra su aplicación y luego la reinstala, la clave/valores seguirán estando accesibles.

+0

Este código funcionó bien para mí en el simulador con iOS 4.3 – AlBeebe

+2

Hay un error en Selector getSecureValueForKey: cuando devuelve el valor, ya está liberado. Es lanzado por "[resultado de lanzamiento];" –

+0

Modifiqué para ser funciones C en lugar de métodos Objective-C. En mi caso, me gustaría que esta funcionalidad esté disponible para cualquier objeto en mi aplicación, y la funcionalidad en sí misma no parece requerir ningún tipo de almacenamiento persistente (ivars). Pero de lo contrario, gran fragmento! –

Cuestiones relacionadas