What key should I use to store the password in iOS keychain?

In the KeychainItemWrapper class in the Apple GenericKeychain sample, use the kSecValueData key to store the password.

But the link is http://developer.apple.com/library/ios/#documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898

says that kSecValueData is used in the result dictionary for SecItemCopyMatching or SecItemAdd, indicating the type of return values.

which key should I use when I call SecItemAdd to create a keychain element?

+6
source share
1 answer

You must use the kSecValue data as a key to store the password (in NSData or CFDataRef format).

The link is a bit unclear in this question, the kSecValueData key works both the output key and the input key. That is, you use it when you request the keychain element (SecItemCopyMatching) and specify the key kSecReturnAttributes, so the result is returned as a dictionary, the password will be stored under the key kSecValueData of this dictionary. And you also use it when you add an item to the keychain (SecItemAdd), storing the NSData or CFDataRef value of your password in the kSecValueData key before calling the method.

Here is an example of both cases:

Reception of the password:

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 the queried password value NSData *passwordValue = [resultDict objectForKey:(__bridge id)(kSecValueData)]; } 

Adding a password:

 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 } 
+7
source

Source: https://habr.com/ru/post/946518/


All Articles