6

Apple GenericKeychain サンプルの KeychainItemWrapper クラスは、kSecValueData キーを使用してパスワードを保存します。

しかし、参照http://developer.apple.com/library/ios/#documentation/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898

kSecValueData は SecItemCopyMatching または SecItemAdd の結果ディクショナリで使用され、返される値のタイプを示します。

キーチェーン アイテムを作成するために SecItemAdd を呼び出す場合、どのキーを使用すればよいですか?

4

1 に答える 1

7

パスワードを格納するキーとして 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
}
于 2013-07-11T08:34:56.657 に答える