iOS开发第三方SSKeychain保存用户密码

释放双眼,带上耳机,听听看~!

UDID(-[UIDevice uniqueIdentifier])在iOS7.0被禁用,一般使用UUID来作为设备的唯一标识

获取到UUID后,如果用NSUserDefaults存储,当程序被卸载后重装时,再获得的UUID和之前就不同了。
使用keychain存储可以保证程序卸载重装时,UUID不变。但当刷机或者升级系统后,UUID还是会改变的。

测试发现:
程序一(test1):

    NSLog(@"--%@--", [UIDevice currentDevice].identifierForVendor.UUIDString);
//模拟器6 8.1:   547B1AE8-483D-4740-A668-AC600A6EA7F4
//卸载后重新运行: 547B1AE8-483D-4740-A668-AC600A6EA7F4
//模拟器6 9.2:  4572DE5F-5E98-4C1A-A9FD-E32A12530469

程序二(test2):

    NSLog(@"--%@--", [UIDevice currentDevice].identifierForVendor.UUIDString);
//模拟器6 8.1:   547B1AE8-483D-4740-A668-AC600A6EA7F4
//卸载后重新运行: 547B1AE8-483D-4740-A668-AC600A6EA7F4
//模拟器6 9.2:  4572DE5F-5E98-4C1A-A9FD-E32A12530469

1. keychain的功能


keychain的主要功能就是帮助用户安全地记住他的密码,keychain保存的密码文件都是经过加密的,其它人不能直接通过打开keychain的文件获得保存在keychain中的密码.

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

苹果官方:Keychain Services Programming Guide

苹果官方: Keychain Services Reference

苹果官方代码

>

A keychain is an encrypted container that holds passwords for multiple applications and secure services. Keychains are secure storage containers, which means that when the keychain is locked, no one can access its protected contents. In OS X, users can unlock a keychain—thus providing trusted applications access to the contents—by entering a single master password. In iOS, each application always has access to its own keychain items; the user is never asked to unlock the keychain. Whereas in OS X any application can access any keychain item provided the user gives permission, in iOS an application can access only its own keychain items.

钥匙链是一个加密的容器,它保存了多个程序和安全服务的密码。钥匙链是一个安全的存储容器,这意味着没有应用程序或服务在它锁住的情况下,可以访问它的内容。在Mac OS X下,用户可以解锁钥匙链,因此可以通过输入主密码的形式提供给信任的应用程序访问里面的内容。在iOS中,每个应用程序只能访问自己的钥匙链项;用户不能解锁钥匙链。相反在Mac OS X里,用户给予了许可,每个应用程序都能访问任何一个钥匙链项。在iOS里,一个应用程序只能访问自己的钥匙链项。

Note: On iPhone, Keychain rights depend on the provisioning profile used to sign your application. Be sure to consistently use the same provisioning profile across different versions of your application.

注意:在iPhone中,钥匙链依赖于 provisioning profile 文件来标识你的应用程序。确保应用程序在不同版本中一贯的使用同一个 provisioning profile 文件

In iOS,there is a single keychain accessible to applications. Although it stores the keychain items of all the applications on the system, an application can access only its own keychain items (with the possible exception of a keychain item for which the application that created it obtained a persistent reference).

在iOS里,有一个单独的钥匙链供应用程序访问。尽管他存储了系统里全部应用程序的钥匙链项,一个应用程序只能并且仅能访问它自己的钥匙链项(包括因为应用程序创建包含了一个持久的引用二引发的可能的钥匙链项异常)

Structure of a Keychain
Each keychain can contain any number of keychain items. Each keychain item contains data plus a set of attributes. For a keychain item that needs protection, such as a password or private key (a string of bytes used to encrypt or decrypt data), the data is encrypted and protected by the keychain. For keychain items that do not need protection, such as certificates, the data is not encrypted.

钥匙链结构
每一个钥匙链可以包含任意数量的钥匙链项。每个钥匙链项包含数据加上一些属性集。对一个钥匙链项来说需要进行保护,比如像一个密码或这个私有键(加密或者揭秘的二进制数据字符串),数据被钥匙链加密和保护。对多个钥匙链项来说不需要保护,比如像证书,它的数据是不加密的。

The iOS gives an application access to only its own keychain items.

在iOS中,仅给一个用程序访问它自己的钥匙项权限。

The iOS Keychain Services API uses a different paradigm. This API has a single function (SecItemAdd) for adding an item to a keychain.

在iOS钥匙链服务API使用了一个不同的范式(相对于Mac OS X)。这个API有一个单独的函数(SecItemAdd)来添加一个钥匙链项。

In iOS, you call the SecItemCopyMatching function to find a keychain item owned by your application. In this case there’s only one keychain and the user is never prompted to unlock it.

在iOS中,你调用SecItemCopyMatching函数来查找你应用程序自己的钥匙链项目。在这种情况下,仅有一个钥匙链并且用户不需要被提示来解锁它(相对于Mac OS X)。

iOS钥匙链服务搜索字典

在iOS,钥匙链服务使用键值对字典方式来制定钥匙链项的属性,这样你就能查找或者创建。

经典的搜索字典组成:

class key:用来指定要搜索的钥匙链项的类型(比如,互联网密码 或者密码密钥)。

一个或多个键值对来指定匹配属性数据(比如标签或者创建日期)

一个或多个搜索键值对,用来指定值来精确搜索,比如发行证书或者邮件地址来匹配。

一个返回值键值对,来指定你想要的数据(比如。一个字典或者是一个偏好引用)。
什么样的属性值被指定,取决于你要搜索的钥匙链项的类型。举例,如果你指定键位kSecClass的值为kSecClassGenericPassword,然后你可以指定创建时间的值或这个修改时间的值,但是不能指定主题或发行者(这个被用于证书)。

举例,如果你想执行一个对AppStore账户名为’ImaUser’密码不敏感情况的搜索,你可以在SecItemCopyMatching函数,使用上面表格中的键值对。

kSecReturnData键是函数返回钥匙链项的数据,如果你想得到键值对的值,你需要使用kSecReturnAttributes返回类型键并且值为kCFBooleanTrue.

2. iOS中使用keychain和userdefaults保存数据的对比


1. userdefault适合保存一些轻量级的数据,使用userdefault保存的数据加载的时候要快一些,数据以明文的形式保存在.plist文件中,不适合用来保存密码信息。文件的位置是Library/Application Support/iPhone Simulator/模拟器版本/Applications/应用对应的数字/Library/Preference/.plist文件

2. keychain采用的是将数据加密之后再保存到本地的,这样对数据而言有更高的安全性,适合保存密码之类的数据。数据保存的目录是Library/Application Support/iPhone Simulator/模拟器版本/Library/Keychains/

3. SSKeychain的使用


github地址: https://github.com/samsoffes/sskeychain

SSKeychain对apple安全框架API进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置;

在工程中加入SSKeyChain

方法一: 手动添加
在工程中加入Security.framework框架。
SSKeychain.hSSKeychain.m加到项目文件夹。

方法二: 使用第三方管理工具
pod 'SSKeychain', '~> 1.3.1'

使用

SSKeyChain使用起来非常的简单, 方法也不多

//获取所有账号
+ (NSArray *)allAccounts;
//获取某个服务下的所有账号
+ (NSArray *)accountsForService:(NSString *)serviceName;
//设置特定服务下的给定账号的密码
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;
//获取某个服务下的某个账号的密码
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
//删除某个服务下的某个账号的密码
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;

注意:

  1. 以上方法中的serviceNameaccount 参数应该是一致的这样才能保证真确的操作, 建议使用宏定义 或者 static NSString *kServiceName = @"ServiceName";
  2. 如果你保存密码失败,处理方法:
NSError *error = nil;
NSString *password = [SSKeychain passwordForService:@"自定义的服务器名" account:@"账号" error:&error];
if ([error code] == SSKeychainErrorNotFound) {
NSLog(@"该账户没有储存密码");
//you should do something more sophisticated
}  

参考文档:
1. https://github.com/samsoffes/sskeychain
2. http://www.ithao123.cn/content-2407927.html
3. https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html#//apple_ref/doc/constant_group/Keychain_Import_Export_Options
4. http://www.kanyinqing.com/read/it/other/445654.html

人已赞赏
iOS文章

iOS开发NSDate+Addition

2020-3-4 19:14:24

iOS文章

iOS废弃API取消出现Warning的方法

2020-3-5 1:09:35

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索