iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式。每个ios程序都有一个独立的keychain存储。从ios 3.0开始,跨程序分享keychain变得可行。



下面就使用keychain来实现存取用户名和密码。



苹果已经有现成的类封装好了keychain,KeychainItemWrapper.h和KeychainItemWrapper.m文件,可以在GenericKeychain实例里找到。



但是这里我只需要存取用户名和密码,就不用苹果提供的类了,自己写个简单的类来实现就好。



代码如下:



CHKeychain.h

  1. #import
  2. #import
  3. @interface CHKeychain : NSObject
  4. + (void)save:(NSString *)service data:(id)data;
  5. + (id)load:(NSString *)service;
  6. + (void)delete:(NSString *)service;
  7. @end

CHKeychain.m

  1. #import "CHKeychain.h"
  2.  
  3. @implementation CHKeychain
  4. + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
  5. return [NSMutableDictionary dictionaryWithObjectsAndKeys:
  6. (id)kSecClassGenericPassword,(id)kSecClass,
  7. service, (id)kSecAttrService,
  8. service, (id)kSecAttrAccount,
  9. (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
  10. nil];
  11. }
  12.  
  13. + (void)save:(NSString *)service data:(id)data {
  14. //Get search dictionary
  15. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  16. //Delete old item before add new item
  17. SecItemDelete((CFDictionaryRef)keychainQuery);
  18. //Add new object to search dictionary(Attention:the data format)
  19. [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
  20. //Add item to keychain with the search dictionary
  21. SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
  22. }
  23.  
  24. + (id)load:(NSString *)service {
  25. id ret = nil;
  26. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  27. //Configure the search setting
  28. //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
  29. [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
  30. [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
  31. CFDataRef keyData = NULL;
  32. if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
  33. @try {
  34. ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];
  35. } @catch (NSException *e) {
  36. NSLog(@"Unarchive of %@ failed: %@", service, e);
  37. } @finally {
  38. }
  39. }
  40. if (keyData)
  41. CFRelease(keyData);
  42. return ret;
  43. }
  44.  
  45. + (void)delete:(NSString *)service {
  46. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  47. SecItemDelete((CFDictionaryRef)keychainQuery);
  48. }
  49. @end

首先需要定义几个字符串用来做key:

  1. NSString * const KEY_USERNAME_PASSWORD = @"com.company.app.usernamepassword";
  2. NSString * const KEY_USERNAME = @"com.company.app.username";
  3. NSString * const KEY_PASSWORD = @"com.company.app.password";

把用户名和密码存入keychain:

  1. NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary];
  2. [usernamepasswordKVPairs setObject:txtfldUsername.text forKey:KEY_USERNAME];
  3. [usernamepasswordKVPairs setObject:txtfldPassword.text forKey:KEY_PASSWORD];
  4. [CHKeychain save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs];

从keychain中取出用户名和密码:

  1. NSMutableDictionary *usernamepasswordKVPairs = (NSMutableDictionary *)[CHKeychain load:KEY_USERNAME_PASSWORD];
  2. txtfldUsername.text = [usernamepasswordKVPairs objectForKey:KEY_USERNAME];
  3. txtfldPassword.text = [usernamepasswordKVPairs objectForKey:KEY_PASSWORD];

删除一个keychain item:

  1. [CHKeychain delete:KEY_USERNAME_PASSWORD];

这样一个简单的使用keychain存取用户名密码的功能就做好了。



另外附上一篇写得更详细的e文:http://useyourloaf.com/blog/2010/3/29/simple-iphone-keychain-access.html

iOS开发——密码存储之keychain的使用的更多相关文章

  1. IOS开发数据存储篇—IOS中的几种数据存储方式

    IOS开发数据存储篇—IOS中的几种数据存储方式 发表于2016/4/5 21:02:09  421人阅读 分类: 数据存储 在项目开发当中,我们经常会对一些数据进行本地缓存处理.离线缓存的数据一般都 ...

  2. iOS开发-数据存储NSCoder

    软件中永远绕不开的一个问题就是数据存储的问题,PC的时候一般都是选择在数据库中存储,iOS如果是和后端配合的话,那么不需要考虑数据存储的这个问题,上次写了一下plist的存储,不过数据都是存储一些简单 ...

  3. iOS开发-本地存储(偏好设置,Plist,归档)

    1.   NSUserDefaults //TODO: 1.NSUserDefaults NSUserDefaults类除了可以存储数组.字典.NSdata外,还可以直接存储OC基本类型属性.但是不能 ...

  4. iOS开发密码输入数字和字母混合

    #import "TestInPut.h" @implementation TestInPut +(BOOL)judgePassWordLegal:(NSString *)pass ...

  5. iOS开发-获取属性和方法

    iOS开发数据存储有两种方式,属性列表和对象编码,属性列表可以通过NSArray,NSMutableArray,NSMutableDictionary,存储对象我们可以通过归档和解档来完成.如果我们想 ...

  6. iOS开发 数据缓存-数据库

    iOS中数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding (NSKeyedArchiver\NSk ...

  7. iOS 应用开发,用户密码存储技术--KeyChain

    文/清雪飘香(简书作者)原文链接:http://www.jianshu.com/p/c41525172aee著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 这次的Xcode 事件,让我 ...

  8. iOS开发技术分享(1)— iOS本地数据存储

    iOS开发技术分享(1)— iOS本地数据存储 前言: 我本是一名asp.net程序员,后来加入了iOS游戏开发队伍,到现在也有一年多的时间了.这一年来,每天都干到2.3点钟才睡觉,不为别的,只为了学 ...

  9. iOS开发UI篇—ios应用数据存储方式(偏好设置)

    iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...

随机推荐

  1. SQL Server2019数据库备份与还原脚本,数据库可批量备份

    前言 最近公司服务器到期,需要进行数据迁移,而数据库属于多而繁琐,通过图形化界面一个一个备份所需时间成本很大,所以想着写一个sql脚本来执行. 开始 数据库单个备份 数据库批量备份 数据库还原 数据库 ...

  2. [cf1326F]Wise Men

    对答案序列求一个高维后缀和,再通过差分将其解出,后者复杂度为$o(n2^{n})$ 对于求后缀和后的结果,即01序列仅要求1处有边(不要求0处没有边),那么也即要求将原图划分为若干条长度给定且没有公共 ...

  3. [loj3247]Non-Decreasing Subsequences

    分治,考虑分治到[l,r]的区间(设$mid=(l+r)/2$),将询问分为两类:1.在左/右区间,直接递归下去:2.跨越中间,那么处理出两个数组:L[i][j]表示左区间在开头第i个位置,以数字j为 ...

  4. Spark SQL知识点与实战

    Spark SQL概述 1.什么是Spark SQL Spark SQL是Spark用于结构化数据(structured data)处理的Spark模块. 与基本的Spark RDD API不同,Sp ...

  5. Kubernetes-网络

    前言 本篇是Kubernetes第十一篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战,此篇文章概念比较多,后续我会继续出一些网络相关实战以及原理探索篇. Kubernetes系列文章: K ...

  6. 全面了解 Javascript Prototype Chain 原型链

    原型链可以说是Javascript的核心特征之一,当然也是难点之一.学过其它面向对象的编程语言后再学习Javascript多少会感到有些迷惑.虽然Javascript也可以说是面向对象的语言,但是其实 ...

  7. 文件/目录对比:diff命令

    命令格式 diff [参数] [文件1或目录1] [文件2或目录2] Linux diff命令用于比较文件的差异. diff以逐行的方式,比较文本文件的异同处. 如果指定要比较目录,diff会比较目录 ...

  8. SUNTANS 及 FVCOM 对流扩散方程求解简介[TBC]

    最近接到一个任务,就是解决FVCOM中对流扩散计算不守衡问题.导师认为是其求解时候水平和垂向计算分开求解所导致的,目前我也没搞清到底有什么问题,反正就是让把SUNTANS的对流扩散计算挪到FVCOM中 ...

  9. MybatisPlus使用Wrapper实现查询功能

    Wrapper---条件查询器 :使用它可以实现很多复杂的查询 几个案例 环境: 参照博客:MybatisPlus入门程序 1.条件查询 1.1 查询name不为空的用户,并且邮箱不为空的用户,年龄大 ...

  10. 『学了就忘』Linux文件系统管理 — 65、LVM逻辑卷管理介绍

    目录 1.LVM逻辑卷管理的简介 2.LVM逻辑卷管理的原理 3.总结建立LVM分区的步骤 1.LVM逻辑卷管理的简介 LVM是Logical Volume Manager的简称,中文就是逻辑卷管理. ...