Apple GenericKeychain サンプルの KeychainItemWrapper クラスは、kSecValueData キーを使用してパスワードを保存します。
kSecValueData は SecItemCopyMatching または SecItemAdd の結果ディクショナリで使用され、返される値のタイプを示します。
キーチェーン アイテムを作成するために SecItemAdd を呼び出す場合、どのキーを使用すればよいですか?
Apple GenericKeychain サンプルの KeychainItemWrapper クラスは、kSecValueData キーを使用してパスワードを保存します。
kSecValueData は SecItemCopyMatching または SecItemAdd の結果ディクショナリで使用され、返される値のタイプを示します。
キーチェーン アイテムを作成するために SecItemAdd を呼び出す場合、どのキーを使用すればよいですか?
パスワードを格納するキーとして kSecValue データを使用する必要があります (NSData または CFDataRef 形式)。
このテーマでは参照が少し不明確ですが、kSecValueData キーは入力キーだけでなく出力キーとしても機能します。つまり、キーチェーン アイテム (SecItemCopyMatching) をクエリして kSecReturnAttributes キーを指定するときに使用します。結果は辞書として返され、パスワードはその辞書の kSecValueData キーに格納されます。また、キーチェーン (SecItemAdd) にアイテムを追加するときにも使用し、メソッドを呼び出す前にパスワードの NSData または CFDataRef 値を kSecValueData キーに格納します。
両方のケースの例を次に示します。
パスワードの取得:
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)];
}
パスワードの追加:
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
}