标签:
我们在开放APP时,通常要把一些比较重要的用户信息保留到APP中,我们很多时候的做法是直接裸存到NSUserDefaults。这种做法的很明显的缺点是不够安全,以下我们将用代码封装一个类,把用户名账号密码等比较重要的信息保存到苹果自带的钥匙串中,这样除非整个iOS的安全机制被破解,要不然你储存的东西就会相对的安全,这样做还有一个好处就是,当用户删除该APP,重新下载安装了,也能读取到之前保存到钥匙串里的数据。
直接上代码:
.h
// // KeychainTool.h // 密码保存到钥匙串 // // Created by HO on 16/6/9. // Copyright © 2016年 HO. All rights reserved. // #import <Foundation/Foundation.h> #import <Security/Security.h> @interface YFKeychainTool : NSObject /** * 储存字符串到??钥匙串 * * @param sValue 对应的Value * @param sKey 对应的Key */ + (void)saveKeychainValue:(NSString *)sValue key:(NSString *)sKey; /** * 从??钥匙串获取字符串 * * @param sKey 对应的Key * * @return 返回储存的Value */ + (NSString *)readKeychainValue:(NSString *)sKey; /** * 从??钥匙串删除字符串 * * @param sKey 对应的Key */ + (void)deleteKeychainValue:(NSString *)sKey; @end
.m
// // KeychainTool.m // 密码保存到钥匙串 // // Created by HO on 16/6/9. // Copyright © 2016年 HO. All rights reserved. // #import "YFKeychainTool.h" @implementation YFKeychainTool + (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)saveKeychainValue:(NSString *)sValue key:(NSString *)sKey{ NSMutableDictionary * keychainQuery = [self getKeychainQuery:sKey]; SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery); [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:sValue] forKey:(__bridge_transfer id)kSecValueData]; SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL); } + (NSString *)readKeychainValue:(NSString *)sKey { NSString *ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey]; [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 CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { @try { ret = (NSString *)[NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", sKey, e); } @finally { } } if (keyData) CFRelease(keyData); return ret; } + (void)deleteKeychainValue:(NSString *)sKey { NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey]; SecItemDelete((__bridge CFDictionaryRef)keychainQuery); } @end
ViewController 调用
// // ViewController.m // 密码保存到钥匙串 // // Created by HO on 16/6/9. // Copyright © 2016年 HO. All rights reserved. // #import "ViewController.h" #import "YFKeychainTool.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UITextField *userName; @property (weak, nonatomic) IBOutlet UITextField *password; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)saveBtn:(id)sender { [YFKeychainTool saveKeychainValue:self.userName.text key:@"userName"]; [YFKeychainTool saveKeychainValue:self.password.text key:@"password"]; } - (IBAction)readeBtn:(id)sender { self.userName.text = [NSString stringWithFormat:@"读取到用户名:%@",[YFKeychainTool readKeychainValue:@"userName"]]; self.password.text = [NSString stringWithFormat:@"读取到用户密码:%@",[YFKeychainTool readKeychainValue:@"password"]]; } - (IBAction)deleteBtn:(id)sender { [YFKeychainTool deleteKeychainValue:@"userName"]; [YFKeychainTool deleteKeychainValue:@"password"]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
效果图:
标签:
原文地址:http://www.cnblogs.com/HOYF/p/5608299.html