2013-06-04 11 views
6

Klasa KeychainItemWrapper w kluczu Apple GenericKeychain przy użyciu klucza kSecValueData do przechowywania hasła.którego klucza należy użyć do przechowywania hasła w pęku kluczy systemu iOS?

Jednak odniesienie http://developer.apple.com/library/ios/#documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898

mówi kSecValueData jest stosowane w słowniku wyników dla SecItemCopyMatching lub SecItemAdd, wskazując rodzaj wartości zwracanych.

Który klucz powinienem użyć, gdy zadzwonię do SecItemAdd, aby utworzyć element pęku kluczy?

Odpowiedz

7

Należy użyć danych kSecValue jako klucza do przechowywania hasła (w formacie NSData lub CFDataRef).

Odniesienie jest nieco niejasne w tym temacie, klucz kSecValueData działa zarówno jako klucz wyjściowy, jak i klawisz wprowadzania. Oznacza to, że używasz go, gdy wyszukujesz element pęku kluczy (SecItemCopyMatching) i określasz klucz kSecReturnAttributes, więc wynik jest zwracany jako słownik, hasło zostanie zapisane pod kluczem kSecValueData tego słownika. Używa się go również, gdy dodajesz element do pęku kluczy (SecItemAdd), przechowując wartość NSData lub CFDataRef swojego hasła w kluczu kSecValueData przed wywołaniem metody.

Oto przykład obu przypadkach:

Odzyskiwanie hasła:

NSMutableDictionary *queryDictionary = [[NSMutableDictionary alloc] init]; 
[queryDictionary setObject: (__bridge id)kSecClassGenericPassword forKey: (__bridge id<NSCopying>)kSecClass]; 
[queryDictionary setObject:service forKey:kSecAttrService]; 
[queryDictionary setObject:account forKey:kSecAttrAccount]; 
// The result will be a dictionary containing the password attributes... 
[queryDictionary setObject:YES forKey:(__bridge id<NSCopying>)(kSecReturnAttributes)]; 
// ...one of those attributes will be a kSecValueData with the password 
[queryDictionary setObject:YES forKey:(__bridge id<NSCopying>)(kSecReturnData)]; 
OSStatus sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)(queryDictionary), (CFTypeRef *)&result); 
if (sanityCheck != noErr) 
{ 
    NSDictionary * resultDict = (__bridge NSDictionary *)result; 
    // here's the queried password value 
    NSData *passwordValue = [resultDict objectForKey:(__bridge id)(kSecValueData)]; 
} 

Dodawanie hasło:

NSString *passwordString = @"my password value"; 
NSData *passwordData = [passwordString dataUsingEncoding:NSUTF8StringEncoding]; 
CFDictionaryRef result = nil; 
NSMutableDictionary *addDictionary = [[NSMutableDictionary alloc] init]; 
[addDictionary setObject: (__bridge id)kSecClassGenericPassword forKey: (__bridge id<NSCopying>)kSecClass]; 
[addDictionary setObject:service forKey:kSecAttrService]; 
[addDictionary setObject:account forKey:kSecAttrAccount]; 

// here goes the password value 
[addDictionary setObject:passwordData forKey:(__bridge id<NSCopying>)(kSecValueData)]; 

OSStatus sanityCheck = SecItemAdd((__bridge CFDictionaryRef)(queryDictionary), NULL) 
if (sanityCheck != noErr) 
{ 
    // if no error the password got successfully stored in the keychain 
} 
+0

Lepsze kod, z mniejszą ilością błędów, tutaj: http://stackoverflow.com/questions/19284063/secitemcopymatching-returns-nil-data –

Powiązane problemy