钥匙串 keyChain 存储账号密码
来源:互联网 发布:开淘宝的经验分享 编辑:程序博客网 时间:2024/05/02 02:16
目前我们存储账号密码,一般存在 偏好设置表里,如果明文存储,安全上又有很大隐患,所以今天给大家推荐一种更安全的密码存储方式。
不知道大家是否注意过,当我们使用百度系列的产品时,比如说:我登录上了百度糯米app后,然后我又下载了一个百度云盘,当我打开百度云盘app的时候,我居然自动登录了!这里就是用到了keyChain来保存账号密码,并通过应用组的方式在 应用间共享一套账户密码。
iOS设备中的keyChain是一个安全的存储容器,可以用来为不同应用保存敏感信息(用户名,密码,网络密码等)。同时,keyChain是一个相对独立的空间,当应用替换或删除时并不会删除keyChain的内容,目前看来,使用keyChain来保存用户名和用户密码是最优的解决方案。
本例本着简单易用的原则,提供了一些利用keyChain对账号信息进行增、删、改、查的功能。
先看一下使用:
#import "ViewController.h"#import "GZKeyChain.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //保存或更新 [GZKeyChain saveUserName:@"张三" pwd:@"asdfghjkl"]; [GZKeyChain saveUserName:@"lisi" pwd:@"asrtyui"]; [GZKeyChain saveUserName:@"张三" pwd:@"rtghnm,loi"];//会覆盖先前密码 //查询所有用户的账号密码 NSDictionary *dic = [GZKeyChain loadAccountInfo]; NSLog(@"dic = %@",dic); //查询某一用户的账号密码 NSString *pwd = [GZKeyChain loadPwdForUserName:@"lisi"]; NSLog(@"userPwd = %@",pwd); //删除某一用户的账号密码 [GZKeyChain removeForUserName:@"张三"]; NSLog(@"dic1 = %@",[GZKeyChain loadAccountInfo]); //删除所有用户的账号密码 [GZKeyChain removeAll]; NSLog(@"dic2 = %@",[GZKeyChain loadAccountInfo]);}@end
工具实现
// 需要引入 Security 框架
.h
#import <Foundation/Foundation.h>#import <Security/Security.h>@interface GZKeyChain : NSObject/** 保存或更新 用户名、密码 */+ (void)saveUserName:(NSString *)userName pwd:(NSString *)pwd;+ (void)saveUserName:(NSString *)userName pwd:(NSString *)pwd service:(NSString *)service;/** 加载所有 用户名、密码 信息 。 key:用户名, value:密码 */+ (NSDictionary *)loadAccountInfo;+ (NSDictionary *)loadAccountInfoWithService:(NSString *)service;/** 加载某一用户的密码 */+ (NSString *)loadPwdForUserName:(NSString *)userName;+ (NSString *)loadPwdForUserName:(NSString *)userName service:(NSString *)service;/** 移除所有账号信息 */+ (void)removeAll;+ (void)removeAllWithService:(NSString *)service;/** 移除某一账号的密码信息 */+ (void)removeForUserName:(NSString *)userName;+ (void)removeForUserName:(NSString *)userName service:(NSString *)service;@end
.m
#import "GZKeyChain.h"@implementation GZKeyChain+ (NSString *)defaultService{ return [[NSBundle mainBundle] bundleIdentifier] ? : @"";}+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service { if (!service) service = self.defaultService; return [NSMutableDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword,(id)kSecClass, service, (id)kSecAttrService, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil];}#pragma mark 写入+ (void)saveUserName:(NSString *)userName pwd:(NSString *)pwd{ [self saveUserName:userName pwd:pwd service:nil];}+ (void)saveUserName:(NSString *)userName pwd:(NSString *)pwd service:(NSString *)service{ if (![userName isKindOfClass:[NSString class]]) return; if (!userName || !pwd) return; NSMutableDictionary *query = [self getKeychainQuery:service]; NSDictionary *results = [self loadAccountInfoWithService:service]; SecItemDelete((CFDictionaryRef)query); NSMutableDictionary *dataDic = [NSMutableDictionary dictionaryWithDictionary:results ?:@{}]; [dataDic setObject:pwd forKey:userName]; [query setObject:[NSKeyedArchiver archivedDataWithRootObject:dataDic] forKey:(id)kSecValueData]; SecItemAdd((CFDictionaryRef)query, NULL);}#pragma mark 读取+ (NSDictionary *)loadAccountInfo{ return [self loadAccountInfoWithService:nil];}+ (NSDictionary *)loadAccountInfoWithService:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; [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:(__bridge NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } if (keyData) CFRelease(keyData); return ret;}+ (NSString *)loadPwdForUserName:(NSString *)userName{ return [self loadPwdForUserName:userName service:nil];}+ (NSString *)loadPwdForUserName:(NSString *)userName service:(NSString *)service{ if (!userName) return nil; NSDictionary *results = [self loadAccountInfoWithService:service]; if (![results isKindOfClass:[NSDictionary class]]) return nil; return [results objectForKey:userName];}#pragma mark 删除+ (void)removeAll{ [self removeAllWithService:nil];}+ (void)removeAllWithService:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)keychainQuery);}+ (void)removeForUserName:(NSString *)userName{ [self removeForUserName:userName service:nil];}+ (void)removeForUserName:(NSString *)userName service:(NSString *)service{ NSDictionary *results = [self loadAccountInfoWithService:service]; if (!results) return; NSMutableDictionary *dataDic = [NSMutableDictionary dictionaryWithDictionary:results]; [dataDic removeObjectForKey:userName]; NSMutableDictionary *query = [self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)query); [query setObject:[NSKeyedArchiver archivedDataWithRootObject:dataDic] forKey:(id)kSecValueData]; SecItemAdd((CFDictionaryRef)query, NULL);}@end
觉得对你有用就给个 star 支持一下吧!详细demo下载
如有问题,欢迎评论交流!
0 0
- 钥匙串 keyChain 存储账号密码
- 工作备忘-钥匙串存储UUID和账号密码
- iOS 钥匙串KeyChain
- IOS 用keychain(钥匙串)保存用户名和密码
- IOS 用keychain(钥匙串)保存用户名和密码
- 用keychain(钥匙串)保存用户名和密码
- IOS中使用sskeychain调用keychain(钥匙串)保存密码
- IOS 用keychain(钥匙串)保存用户名和密码
- iOS获取UUID,并使用keychain存储,将账号密码存到keychain中
- iOS 用keychain钥匙串保存账号、设备UUID及APP间共享
- iOS钥匙串Keychain浅析
- keychain service钥匙串服务
- 钥匙串KeyChain的使用
- IOS在钥匙串里保存APP的账号密码
- Firemonkey访问iOS的钥匙串Keychain
- iOS Keychain (钥匙串)简单封装
- ios - 钥匙串开发(keychain开发)
- 用keychain保存用户的账号,密码,uuid
- Error Curves HDU
- 309. Best Time to Buy and Sell Stock with Cooldown(unsolved)
- 自定义控件(30)---绘图区域(Range)
- 455. Assign Cookies
- 安装zookeeper
- 钥匙串 keyChain 存储账号密码
- 微信小程序、SSL证书、开启服务器TSL1.0、TSL1.1、TSL1.2服务
- c#异常处理
- Elasticsearch windows 安装
- 【转】Tomcat启动慢解决方案
- AndroidFFmpeg
- String中的equals方法
- forward内部跳转 和redirect重定向跳转的区别
- 微信分享失败