Ajout de key privée dans iOS Keychain

J'essaie d'append une key privée dans le trousseau iOS. Le certificate (key publique) fonctionne bien mais la key privée refuse … Je suis totalement confus pourquoi le code suivant ne fonctionne pas.

D'abord, je vérifie si la key actuelle (= dans le cas où Keychain est un magasin de key / valeur) est "libre" dans le Keychain. Ensuite, je vais append la key privée.

CFSsortingngRef labelssortingng = CFSsortingngCreateWithCSsortingng(NULL, [key cSsortingngUsingEncoding:NSUTF8SsortingngEncoding], kCFSsortingngEncodingUTF8); NSArray* keys = [NSArray arrayWithObjects:(__bridge id)kSecClass,kSecAttrLabel,kSecReturnData,kSecAttrAccessible,nil]; NSArray* values = [NSArray arrayWithObjects:(__bridge id)kSecClassKey,labelssortingng,kCFBooleanTrue,kSecAttrAccessibleWhenUnlocked,nil]; NSMutableDictionary* searchdict = [NSMutableDictionary dictionaryWithObjects:values forKeys:keys]; CFRelease(labelssortingng); NSMutableDictionary *query = searchdict; CFTypeRef item = NULL; OSStatus error = SecItemCopyMatching((__bridge_retained CFDictionaryRef) query, &item); if (error) { NSLog(@"Error: %ld (statuscode)", error); } if(error != errSecItemNotFound) { SecItemDelete((__bridge_retained CFDictionaryRef) query); } [query setObject:(id)data forKey:(__bridge id)kSecValueData]; OSStatus status = SecItemAdd((__bridge_retained CFDictionaryRef) query, &item); if(status) { NSLog(@"Keychain error occured: %ld (statuscode)", status); return NO; } 

La sortie de debugging est la suivante:

 2012-07-26 15:33:03.772 App[15529:1b03] Error: -25300 (statuscode) 2012-07-26 15:33:11.195 App[15529:1b03] Keychain error occured: -25299 (statuscode) 

Le premier code d'erreur -25300 représente errSecItemNotFound . Donc, il n'y a pas de valeur stockée pour cette key. Ensuite, lorsque j'essaie d'append la key privée dans le trousseau, j'obtiens -25299 ce qui signifie errSecDuplicateItem . Je ne comprends pas cela. Pourquoi cela arrive-t-il?

Quelqu'un at-il une idée ou un indice à ce sujet?

Codes d'erreur d'Apple:

 errSecSuccess = 0, /* No error. */ errSecUnimplemented = -4, /* Function or operation not implemented. */ errSecParam = -50, /* One or more parameters passed to a function where not valid. */ errSecAllocate = -108, /* Failed to allocate memory. */ errSecNotAvailable = -25291, /* No keychain is available. You may need to restart your computer. */ errSecDuplicateItem = -25299, /* The specified item already exists in the keychain. */ errSecItemNotFound = -25300, /* The specified item could not be found in the keychain. */ errSecInteractionNotAllowed = -25308, /* User interaction is not allowed. */ errSecDecode = -26275, /* Unable to decode the provided data. */ errSecAuthFailed = -25293, /* The user name or passphrase you entered is not correct. */ 

Merci d'avance!

Mise à jour # 1: J'ai compris que cela ne fonctionne que pour la première fois. Même lorsque datatables et la key sont différentes, après la première fois stocké dans le trousseau, je ne peux pas stocker d'autres keys.

Le code suivant a fonctionné pour moi:

 NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; [query setObject:(id)kSecClassKey forKey:(id)kSecClass]; [query setObject:(id)kSecAttrAccessibleWhenUnlocked forKey:(id)kSecAttrAccessible]; [query setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData]; //adding access key [query setObject:(id)key forKey:(id)kSecAttrApplicationTag]; //removing item if it exists SecItemDelete((CFDictionaryRef)query); //setting data (private key) [query setObject:(id)data forKey:(id)kSecValueData]; CFTypeRef persistKey; OSStatus status = SecItemAdd((CFDictionaryRef)query, &persistKey); if(status) { NSLog(@"Keychain error occured: %ld (statuscode)", status); return NO; } 

Désolé mais je ne serai jamais capable de déboguer votre code. Apple fournit un exemple de code (KeychainItemWrapper) qui vous permet d'save une string (je me souviens). C'est une grande aide pour la string de key. Il existe une version modifiée de cette class sur le Web, mais elle enregistre et restaure un dictionary (archivé en tant qu'object de données, ce que fait le code Apple à la string). Cela vous permet d'save plusieurs éléments dans une interface au trousseau. L'essentiel est ici Keychain pour NSDictionary / données