用户名密码不能保存在NSUserDefault里面,这个应该是共识。一般是把重要的东西存在keychain里面,keychain是可以被破解的,最好不要明文存储。

keychain里的东西是存在于每个app的沙盒之外的,所以keychain里保存的信息不回因app卸载而丢失。

使用Keychain需要引入Security.framework框架

苹果官方有个GenericKeychain示例代码,不过它不是ARC的,用的时候在Building Phases-> Compile Sources里面找到KeychainItemWrapper.m,给它添加上标志-fno-objc-arc

假如说你只是要保存个用户名密码,那么使用KeychainItemWrapper就够了,具体的用法如下:

1.首先创建一个KeychainItemWrapper对象

KeychainItemWrapper * wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"myKeychainIdentifier" accessGroup:nil];

其中设置accessGroup为nil,表示不在应用之间共享。

2.假如说你要保存用户名和密码,那么就可以调用

[wrapper setObject:username forKey:(id)kSecAttrAccount];

[wrapper setObject:password forKey:(id)kSecValueData];

3.如果要从keychain里面取出保存的用户名或者密码,可以这样

NSString * username = [wrapper objectForKey:(id)kSecAttrAccount];

NSString * password = [wrapper objectForKey:(id)kSecValueData];

可以判断username或者password是不是nil或者@“”,来判定是否从来没存过keychain。


keychain实际是一个数据库,里面保存的所有东西都是加过密的。苹果自己用keychain来保存wifi密码、VPN凭证等。在iOS里面,如果要在app之间共享keychain就要是同一个公司的证书。对于每个app来说,keychain都有两个访问区,私有访问区和公共访问区。私有访问区只对本应用可见,公共访问区可以对多个应用可见,即使用keychain access group声明。

keychain钥匙串中的条目称为SecItem,它是存储在CFDictionary中的。SecItem有五类:通用密码、互联网密码、证书、密钥、身份。大多数情况下使用keychain的时候都是保存通用密码。在钥匙串中搜索某个SecItem的时候,可以根据自己的标识符来搜索。通用密码条目都包含属性kSecAttrGeneric,可以用它来存储标识符。

keychain SecItem

kSecClass定义属于哪一种类型的keychain,不同的类型有不同的attributes,这些attributes定义了这个item的具体信息,每个item可以包含一个密码项来存储对应密码。

钥匙串中的条目都有可搜索的attribute和加过密的value。对于通用密码条目,比较重要的属性有账户kSecAttrAccount、服务kSecAttrService、标识符kSecAttrGeneric.

官方文档里面通用密码条目所有的属性如下:

all attributes of generic password


参考

1.http://my.oschina.net/w11h22j33/blog/206713