iOS的keychain服務提供了一種安全的保存私密信息(密碼,序列號,證書等)的方式。每個ios程序都有一個獨立的keychain存儲。從ios 3.0開始,跨程序分享keychain變得可行。
下面就使用keychain來實現存取用戶名和密碼。
蘋果已經有現成的類封裝好了keychain,KeychainItemWrapper.h和KeychainItemWrapper.m文件,可以在GenericKeychain實例裏找到。
但是這裏我只需要存取用戶名和密碼,就不用蘋果提供的類了,自己寫個簡單的類來實現就好。
代碼如下:
CHKeychain.h
#import <Foundation/Foundation.h> #import <Security/Security.h> @interface CHKeychain : NSObject + (void)save:(NSString *)service data:(id)data; + (id)load:(NSString *)service; + (void)delete:(NSString *)service; @end
CHKeychain.m
#import "CHKeychain.h" @implementation CHKeychain + (NSMutableDictionary *)getKeychainQuery:(NSString *)service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword,(id)kSecClass, service, (id)kSecAttrService, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil]; } + (void)save:(NSString *)service data:(id)data { //Get search dictionary NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Delete old item before add new item SecItemDelete((CFDictionaryRef)keychainQuery); //Add new object to search dictionary(Attention:the data format) [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData]; //Add item to keychain with the search dictionary SecItemAdd((CFDictionaryRef)keychainQuery, NULL); } + (id)load:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Configure the search setting //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; CFDataRef keyData = NULL; if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { @try { ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } if (keyData) CFRelease(keyData); return ret; } + (void)delete:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)keychainQuery); } @end
首先需要定義幾個字符串用來做key:
NSString * const KEY_USERNAME_PASSWORD = @"com.company.app.usernamepassword"; NSString * const KEY_USERNAME = @"com.company.app.username"; NSString * const KEY_PASSWORD = @"com.company.app.password";
把用戶名和密碼存入keychain:
NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary]; [usernamepasswordKVPairs setObject:txtfldUsername.text forKey:KEY_USERNAME]; [usernamepasswordKVPairs setObject:txtfldPassword.text forKey:KEY_PASSWORD]; [CHKeychain save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs];
從keychain中取出用戶名和密碼:
NSMutableDictionary *usernamepasswordKVPairs = (NSMutableDictionary *)[CHKeychain load:KEY_USERNAME_PASSWORD]; txtfldUsername.text = [usernamepasswordKVPairs objectForKey:KEY_USERNAME]; txtfldPassword.text = [usernamepasswordKVPairs objectForKey:KEY_PASSWORD];
刪除一個keychain item:
[CHKeychain delete:KEY_USERNAME_PASSWORD];
這樣一個簡單的使用keychain存取用戶名密碼的功能就做好了。
另外附上一篇寫得更詳細的e文:http://useyourloaf.com/blog/2010/3/29/simple-iphone-keychain-access.html