keychain在kSecValueData中存放Dictionary

我使用的是apple 上提供的sample code KeychainItemWrapper 在此基礎上進行修改 html

相關連接: ios

http://useyourloaf.com/blog/2010/04/28/keychain-duplicate-item-when-adding-password.html app

http://stackoverflow.com/questions/4891562/ios-keychain-services-only-specific-values-allowed-for-ksecattrgeneric-key ide

http://stackoverflow.com/questions/7249297/convert-nsdictionary-to-nsdata ui

1.在keychain的kSecValueData中存儲的數據必須是NSData類型,不然沒法存儲。因此就須要將NSDictionary轉換成NSData this

- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert
{
    // The assumption is that this method will be called with a properly populated dictionary
    // containing all the right key/value pairs for a SecItem.
    
    // Create a dictionary to return populated with the attributes and data.
    NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
    
    // Add the Generic Password keychain item class attribute.
    [returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    
    // Convert the NSString to NSData to meet the requirements for the value type kSecValueData.
	// This is where to store sensitive data that should be encrypted.

    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:[dictionaryToConvert objectForKey:(id)kSecValueData] forKey:@"Some Key Value"];
    [archiver finishEncoding];
    [archiver release];
    

    
    // Here, data holds the serialized version of your dictionary
    // do what you need to do with it before you:
    [returnDictionary setObject:data forKey:(id)kSecValueData];
    [data release];
    return returnDictionary;
}
2.取數據時須要將NSData 轉換成NSDictionary
- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert
{
    // The assumption is that this method will be called with a properly populated dictionary
    // containing all the right key/value pairs for the UI element.
    
    // Create a dictionary to return populated with the attributes and data.
    NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
    
    // Add the proper search key and class attribute.
    [returnDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    
    // Acquire the password data from the attributes.
    NSData *passwordData = NULL;
    //NSMutableDictionary *passwordData = nil;
    if (SecItemCopyMatching((CFDictionaryRef)returnDictionary, (CFTypeRef *)&passwordData) == noErr)
    {
        // Remove the search, class, and identifier key/value, we don't need them anymore.
        [returnDictionary removeObjectForKey:(id)kSecReturnData];
        
        // Add the password to the dictionary, converting from NSData to NSString.
        NSData *d = [[NSMutableData alloc] initWithData:passwordData];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:d];
        NSDictionary *myDictionary = [[unarchiver decodeObjectForKey:@"Some Key Value"] retain];
        [unarchiver finishDecoding];
        [unarchiver release];
        [returnDictionary setObject:myDictionary forKey:(id)kSecValueData];
        [d release];
    }
    else
    {
        // Don't do anything if nothing is found.
        NSAssert(NO, @"Serious error, no matching item found in the keychain.\n");
    }
    
    [passwordData release];
   
	return returnDictionary;
}
3.更改genericPasswordQuery、keychainItemData屬性
[self.genericPasswordQuery setObject:identifier forKey:(id)kSecAttrAccount];

[self.keychainItemData setObject:identifier forKey:(id)kSecAttrAccount];
相關文章
相關標籤/搜索