iOS中使用钥匙串

文件保护用来保护**数据**,而钥匙串则用来保护**秘密**。在这里,秘密是指用来访问其他数据的一小段数据。最常见的秘密就是密码和私钥了。

钥匙串由操作系统保护,在设备锁定时会进行加密处理。实际上,它的工作原理跟文件保护很像。不幸的是,Keychain API并不友好,所以许多开发人员为Keychain API做了一些包装。不过,笔者推荐使用的是苹果GenericKeychain示例代码中的KeyChainItemWrapper。本节将在简要介绍底层的数据结构之后介绍它。


KeyChainItemWrapper有一些问题,其中最突出的问题就是它并不兼容ARC。可以将KeyChainItemWrapper.m文件的ARC关掉,或者增加需要的__bridge类型转换。在网络上搜索GenericKeyChain ARC,可以找到一些做过这方面工作的人写的文章。它并不像我们想的那样方便。有若干种方法都能用来完成这个任务。虽然这些方法都还不成熟,尚不足在这里推荐,但一切都在改进。关注一下iosptl.com上的更新。


钥匙串中的条目称为SecItem,但它是存储在CFDictionary中的。SecItemRef类型并不存在。SecItem有五类:通用密码、互联网密码、证书、密钥和身份。在大多数情况下,我们用到的都是通用密码。许多问题都是开发人员尝试用互联网密码造成的。互联网密码要复杂得多,而且相比之下优势寥寥无几,除非开发Web浏览器,否则没必要用它。KeyChainItemWrapper只使用通用密码,这也是我喜欢它的原因之一。iOS应用很少将密钥和身份存储起来,所以我们在本书中不会讨论这方面的内容。只有公钥的证书通常应该存储在文件中,而不是钥匙串中。

最后,我们需要在钥匙串中搜索需要的内容。密钥有很多个部分可用来搜索,但最好的办法是将自己的标识符赋给它,然后搜索。通用密码条目都包含属性kSecAttrGeneric,可以用它来存储标识符。这也是KeyChainItemWrapper的处理方式。

钥匙串中的条目都有几个可搜索的**属性**和一个加密过的**值**。对于通用密码条目,比较重要的属性有账户(kSecAttrAccount)、服务(kSecAttrService)和标识符(kSecAttrGeneric)。而值通常是密码。

有了这个背景,现在我们可以看看如何使用KeyChainItemWrapper了。首先,如下代码所示,可以用initWithIdentifier:accessGroup:来创建一个密码。稍后介绍访问组的概念,先将它保留为nil

1
2
3
4
KeychainItemWrapper *
  wrapper = [[KeychainItemWrapper alloc]
                               initWithIdentifier:@"MyKeychainItem"
                                      accessGroup:nil];

现在可以对wrapper进行读取和写入了,就跟使用NSDictionary一样。它会自动跟钥匙串同步。__bridge强制转换用来将Core Foundation的常量传给一个使用ARC的Cocoa方法。

1
2
3
4
  id kUsernameKey = (__bridge id)kSecAttrAccount;
  id kPasswordKey = (__bridge id)kSecValueData;
  NSString *username = [wrapper objectForKey:kUsernameKey];
  [wrapper setObject:password forKey:kPasswordKey];

注意,我使用的是个Core Foundation类型(kSecAttrAccount),这里它需要用到idobjectForKey:),不要用类型转换,也不要用__bridge。这是一个新特性。


KeyChainItemWrapper会缓存读入数据,但不会缓存写出的数据。向钥匙串中写数据的成本很高,所以我们不会频繁写入。钥匙串不适合用来存储经常改变的敏感数据。那类数据应该保存到加密文件中,可以参考15.3节的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值