使用keychain來存儲,也就是鑰匙串,使用keychain需要導(dǎo)入Security框架
iOS的keychain服務(wù)提供了一種安全的保存私密信息(密碼刚梭,序列號重慢,證書等)的方式今阳,每個iOS程序都有一個獨立的keychain存儲师溅。相對于 NSUserDefaults、文件保存等一般方式盾舌,keychain保存更為安全墓臭,而且keychain里保存的信息不會因App被刪除而丟失,所以在 重裝App后妖谴,keychain里的數(shù)據(jù)還能使用窿锉。從iOS 3.0開始,跨程序分享keychain變得可行膝舅。
如何需要在應(yīng)用里使 用使用keyChain嗡载,我們需要導(dǎo)入Security.framework ,keychain的操作接口聲明在頭文件SecItem.h里仍稀。直接使用SecItem.h里方法操作keychain洼滚,需要寫的代碼較為復(fù)雜,為減輕 咱們程序員的開發(fā)技潘,我們可以使用一些已經(jīng)封裝好了的工具類遥巴,下面我會簡單介紹下我用過的兩個工具類:KeychainItemWrapper和 SFHFKeychainUtils千康。
自定義一個keychain的類
CSKeyChain.h
@interface CSKeyChain : NSObject
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service;
+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;
@end
CSKeyChain.m
#import "CSKeyChain.h"
#import<Security/Security.h>
@implementation CSKeyChain
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,
service, (__bridge_transfer id)kSecAttrService,
service, (__bridge_transfer id)kSecAttrAccount,
(__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data {
// 獲得搜索字典
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
// 添加新的刪除舊的
SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
// 添加新的對象到字符串
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];
// 查詢鑰匙串
SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
// 配置搜索設(shè)置
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
[keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
} @catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
} @finally {
}
}
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
}
@end
- 在別的類實現(xiàn)存儲,加載,刪除敏感信息方法
// 用來標(biāo)識這個鑰匙串
static NSString * const KEY_IN_KEYCHAIN = @"com.cs.app.allinfo";
// 用來標(biāo)識密碼
static NSString * const KEY_PASSWORD = @"com.cs.app.password";
+ (void)savePassWord:(NSString *)password {
NSMutableDictionary *passwordDict = [NSMutableDictionary dictionary];
[passwordDict setObject:password forKey:KEY_PASSWORD];
[CSKeyChain save:KEY_IN_KEYCHAIN data:passwordDict];
}
+ (id)readPassWord {
NSMutableDictionary *passwordDict = (NSMutableDictionary *)[CSKeyChain load:KEY_IN_KEYCHAIN];
return [passwordDict objectForKey:KEY_PASSWORD];
}
+ (void)deletePassWord {
[CSKeyChain delete:KEY_IN_KEYCHAIN];
}
更多:iOS面試題合集