Dodawanie klucza prywatnego do pęku kluczy iOS
[7]}próbuję dodać klucz prywatny do pęku kluczy iOS. Certyfikat (klucz publiczny) działa poprawnie, ale klucz prywatny odmawia... Jestem całkowicie zdezorientowany, dlaczego poniższy kod nie działa.
Najpierw sprawdzam, czy bieżący klucz (=klucz w przypadku, gdy Pęk kluczy Jest magazynem kluczy/wartości) jest 'wolny' w Pęku Kluczy. Następnie dodam klucz prywatny.
CFStringRef labelstring = CFStringCreateWithCString(NULL, [key cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8);
NSArray* keys = [NSArray arrayWithObjects:(__bridge id)kSecClass,kSecAttrLabel,kSecReturnData,kSecAttrAccessible,nil];
NSArray* values = [NSArray arrayWithObjects:(__bridge id)kSecClassKey,labelstring,kCFBooleanTrue,kSecAttrAccessibleWhenUnlocked,nil];
NSMutableDictionary* searchdict = [NSMutableDictionary dictionaryWithObjects:values forKeys:keys];
CFRelease(labelstring);
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;
}
Wyjście debugowania jest następujące:
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)
Pierwszy kod błędu -25300
reprezentuje errSecItemNotFound
. Więc jest nie ma wartości dla tego klucza. Następnie, gdy próbuję dodać klucz prywatny do pęku kluczy, dostaję -25299
, co oznacza errSecDuplicateItem
. Nie rozumiem tego. Dlaczego to się dzieje?
Czy ktoś ma wskazówkę lub podpowiedź na ten temat?
Kody błędów 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. */
Z góry dzięki!
Aktualizacja # 1: odkryłem, że to działa tylko po raz pierwszy. Nawet jeśli Dane i klucz są różne, po pierwszym zapisaniu w pęku kluczy nie mogę przechowywać kolejnych kluczy.
2 answers
Następujący kod zadziałał dla mnie:
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 11:57:31
Przepraszam, ale nigdy nie będę w stanie debugować Twojego kodu. Apple dostarcza przykładowy kod (KeychainItemWrapper), który pozwala zapisać jeden ciąg znaków (pamiętam). To duża pomoc w radzeniu sobie z breloczkiem. Istnieje gist w sieci, który jest zmodyfikowaną wersją tej klasy, ale zapisuje i przywraca słownik (zarchiwizowany jako obiekt danych, czyli to, co Kod Apple robi z łańcuchem znaków). Pozwala to zapisać wiele elementów w jednym interfejsie do pęku kluczy. Gist jest tutaj Brelok do NSDictionary / data
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-30 08:48:58