iOS开发——密码存储之keychain的使用
iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式。每个ios程序都有一个独立的keychain存储。从ios 3.0开始,跨程序分享keychain变得可行。
下面就使用keychain来实现存取用户名和密码。
苹果已经有现成的类封装好了keychain,KeychainItemWrapper.h和KeychainItemWrapper.m文件,可以在GenericKeychain实例里找到。
但是这里我只需要存取用户名和密码,就不用苹果提供的类了,自己写个简单的类来实现就好。
代码如下:
CHKeychain.h
#import
#import
@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
iOS开发——密码存储之keychain的使用的更多相关文章
- IOS开发数据存储篇—IOS中的几种数据存储方式
IOS开发数据存储篇—IOS中的几种数据存储方式 发表于2016/4/5 21:02:09 421人阅读 分类: 数据存储 在项目开发当中,我们经常会对一些数据进行本地缓存处理.离线缓存的数据一般都 ...
- iOS开发-数据存储NSCoder
软件中永远绕不开的一个问题就是数据存储的问题,PC的时候一般都是选择在数据库中存储,iOS如果是和后端配合的话,那么不需要考虑数据存储的这个问题,上次写了一下plist的存储,不过数据都是存储一些简单 ...
- iOS开发-本地存储(偏好设置,Plist,归档)
1. NSUserDefaults //TODO: 1.NSUserDefaults NSUserDefaults类除了可以存储数组.字典.NSdata外,还可以直接存储OC基本类型属性.但是不能 ...
- iOS开发密码输入数字和字母混合
#import "TestInPut.h" @implementation TestInPut +(BOOL)judgePassWordLegal:(NSString *)pass ...
- iOS开发-获取属性和方法
iOS开发数据存储有两种方式,属性列表和对象编码,属性列表可以通过NSArray,NSMutableArray,NSMutableDictionary,存储对象我们可以通过归档和解档来完成.如果我们想 ...
- iOS开发 数据缓存-数据库
iOS中数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding (NSKeyedArchiver\NSk ...
- iOS 应用开发,用户密码存储技术--KeyChain
文/清雪飘香(简书作者)原文链接:http://www.jianshu.com/p/c41525172aee著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 这次的Xcode 事件,让我 ...
- iOS开发技术分享(1)— iOS本地数据存储
iOS开发技术分享(1)— iOS本地数据存储 前言: 我本是一名asp.net程序员,后来加入了iOS游戏开发队伍,到现在也有一年多的时间了.这一年来,每天都干到2.3点钟才睡觉,不为别的,只为了学 ...
- iOS开发UI篇—ios应用数据存储方式(偏好设置)
iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...
随机推荐
- php开发微信公众号(1)
最近找了个方向提升自己的技术站,发现微信是一个不错的选择 1.入门 申请公众号这些都不说了,另外你必须需要php.h5.MySQL等基本知识才能看懂此文章,还需要有一个服务器及域名,由于我遇见问题也会 ...
- Java 如何对文件进行多个Object对象流的读写操作
思路:把已经序列化的对象存入容器(如LinkedList<?>)中,然后用ObjectInputStream和ObjectOutputStream对这个实例化的LinkedList< ...
- [loj6734]图上的游戏
考虑原图是一条链的情况-- 思路:随机一个点$x$,将其所在段(边集)再划分为两段,重复此过程即可得到该链 实现上,(从左到右)维护每一段的左端点和边集,二分找到最后一个删除后$x$到根不连通的段,那 ...
- [luogu7417]Minimizing Edges P
令$e_{G}(a)$和$o_{G}(a)$分别表示在图$G$中从1到$a$的长度为奇数/偶数的最短路(若该类最短路不存在则为$\infty$),不难得到有以下结论--$f_{G}(a,b)=\beg ...
- [cf1209E]Rotate Columns
题意也可以理解为这样一个过程: 对于每一列,将其旋转后选出若干行上的数,要求与之前的行都不同 用$g_{i,S}$表示第$i$列选出的行数集合为$S$的最大和,$f_{i,S}$表示前$i$列$S$中 ...
- 大厂技术实现 | 腾讯信息流推荐排序中的并联双塔CTR结构 @推荐与计算广告系列
作者:韩信子@ShowMeAI,Joan@腾讯 地址:http://www.showmeai.tech/article-detail/tencent-ctr 声明:版权所有,转载请联系平台与作者并注明 ...
- List集合与Set集合(ArrayList,LinkedList,Vector,HashSet,LinkedHashSet,可变参数)
List集合介绍及常用方法 import java.util.ArrayList; import java.util.Iterator; import java.util.List; /* java. ...
- 详解在Linux中安装配置MongoDB
最近在整理自己私人服务器上的各种阿猫阿狗,正好就顺手详细记录一下清理之后重装的步骤,今天先写点数据库的内容,关于在Linux中安装配置MongoDB 说实话为什么会装MongoDB呢,因为之前因为公司 ...
- Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)
Atcoder 题面传送门 & 洛谷题面传送门 orz ymx,ymx ddw %%% 首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将 ...
- UOJ 422 - 【集训队作业2018】小Z的礼物(Min-Max 容斥+轮廓线 dp)
题面传送门 本来说要找道轮廓线 \(dp\) 的题目刷刷来着的?然后就找到了这道题. 然鹅这个题给我最大的启发反而不在轮廓线 \(dp\),而在于让我新学会了一个玩意儿叫做 Min-Max 容斥. M ...