iOS 钥匙串的基本使用

栏目: IOS · 发布时间: 6年前

内容简介:级别: ★☆☆☆☆标签:「钥匙串」「keychain」「iOS」作者: WYW

级别: ★☆☆☆☆

标签:「钥匙串」「keychain」「iOS」

作者: WYW

审校:QiShare团队

前言 :

项目中有时会需要存储敏感信息(如密码、密钥等),苹果官方提供了一种存储机制-- 钥匙串(keychain)

keychain是一种存储在 硬盘 上的 加密的数据库 。这个可能是卸载App后,keychain信息还在的原因。

keychain适合存储 较小的数据量不超过上千字节或上兆字节 )的内容。

笔者做了一个关于keychain的 增、删、改、查 的Demo(QiKeychain),给大家介绍下keychain的基本使用。

下图(确保keychain中用户的信息安全)有利于我们直观了解keychain。

iOS 钥匙串的基本使用

Demo(QiKeychain)解读:

笔者用Demo(QiKeychain)做了4件事。

  • 增加:存储用户名、密码到keychain;
  • 查询:根据用户名从keychain中查询密码;
  • 删除:从keychain中删除用户名、密码等相应信息;
  • 修改:修改keychain中的用户名对应的密码;

Demo(QiKeychain)对keychain的操作效果如下:

  • 存储用户名 “QiShare”,密码:1234;
  • 查询用户名为“QiShare”的密码,显示密码为:1234;
  • 修改用户名“QiShare”的密码为“123456”;
  • 查询“QiShare”的密码,显示为“123456”;
  • 把“QiShare”从keychain中删除。
iOS 钥匙串的基本使用

keychain基本使用API

keychain有四个常用的API,用于增、删、改、查keychain中的数据。

keychain中的数据子项是以item的形式存在的。

举个例子:就存储用户名、密码的情景来说,每个item包含存储的用户名和密码及其他属性信息,keychain中包含多个用户名和密码的item。

下图(把数据和属性存储到keychain中)利于我们理解存储过程

iOS 钥匙串的基本使用

SecItemAdd:添加一个item或多个items到keychain

OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURNS_RETAINED result)
    API_AVAILABLE(macos(10.6), ios(2.0));
复制代码

存储关键代码:

NSDictionary *saveSecItems = @{(id)kSecClass: (id)kSecClassGenericPassword,
                               (id)kSecAttrService: service,
                               (id)kSecAttrAccount: account,
                               (id)kSecValueData: passwordData
                               };
    OSStatus saveStatus = SecItemAdd((CFDictionaryRef)saveSecItems, NULL);
复制代码

SecItemCopyMatching:返回匹配搜索查询的一个item或多个items

OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RETURNS_RETAINED result)
    API_AVAILABLE(macos(10.6), ios(2.0));
复制代码

查询关键代码:

NSDictionary *matchSecItems = @{
                                    (id)kSecClass: (id)kSecClassGenericPassword,
                                    (id)kSecAttrService: service,
                                    (id)kSecAttrAccount: account,
                                    (id)kSecMatchLimit: (id)kSecMatchLimitOne,
                                    (id)kSecReturnData: @(YES)
                                    };
  CFTypeRef dataRef = nil;
  OSStatus errorCode = SecItemCopyMatching((CFDictionaryRef)matchSecItems, (CFTypeRef *)&dataRef);
复制代码

SecItemUpdate:修改匹配搜索查询的一个item或多个items

OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)
    API_AVAILABLE(macos(10.6), ios(2.0));
复制代码

注意:更新代码这部分,笔者开始的时候遇到一些问题,还要多谢组内成员,尤其是昆哥的指教。

SecItemUpdate接收了2个参数,query和attributesToUpdate。

第一个参数query用于查询到相应的item, 第二个参数attributesToUpdate用于传入要更新的信息。

笔者曾错误地给第二个参数attributesToUpdate传入过(id)kSecClass: (id)kSecClassGenericPassword要更改的内容。

结果报错为:

errSecNoSuchAttr = -25303, /* The specified attribute does not exist. */

更新关键代码:

NSDictionary *queryItems = @{(id)kSecClass: (id)kSecClassGenericPassword,
                               (id)kSecAttrService: service,
                               (id)kSecAttrAccount: account
                               };
    NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *updatedItems = @{
                                   (id)kSecValueData: passwordData,
      };
    OSStatus updateStatus = SecItemUpdate((CFDictionaryRef)queryItems, (CFDictionaryRef)updatedItems);
复制代码

SecItemDelete:删除匹配搜索查询的一个item或多个items

OSStatus SecItemDelete(CFDictionaryRef query)
    API_AVAILABLE(macos(10.6), ios(2.0));
复制代码

删除关键代码:

NSDictionary *deleteSecItems = @{
                                    (id)kSecClass: (id)kSecClassGenericPassword,
                                    (id)kSecAttrService: service,
                                    (id)kSecAttrAccount: account
                                    };
    OSStatus errorCode = SecItemDelete((CFDictionaryRef)deleteSecItems);
复制代码

显然keychain的 增删改查 相关的API都需要设置相应的 属性字典 (分别代指上述的saveSecItems 、matchSecItems 、queryItems 、updatedItems 、deleteSecItems)

  • 属性字典的key、value常用的有:(这部分内容读者也可直接看文档)
  • (id)kSecClass: (id)kSecClassGenericPassword kSecClass表示item的class (id)kSecClass的值表明一个通用的密码item笔者一般都传入kSecClassGenericPassword
  • (id)kSecAttrService: service kSecAttrService的value用于表明item的service
  • (id)kSecAttrAccount: account (id)kSecAttrAccoun的值表明item的帐户名
  • (id)kSecValueData: passwordData (id)kSecValueData表示item的数据
  • (id)kSecMatchLimit: (id)kSecMatchLimitOne, (id)kSecMatchLimit 有2个值(id)kSecMatchLimitOne、和(id)kSecMatchLimitAll kSecMatchLimitOne:表示只匹配第一个符合条件的item kSecMatchLimitAll:表示匹配不限数量的items
  • (id)kSecReturnData: @(YES) (id)kSecReturnData的值是一个Boolean类型的值用于确定是否返回item data
  • kSecClass的值表示item的class kSecClass的值表明一个通用的密码item笔者一般都传入的kSecClassGenericPassword
  • kSecClass的值表示item的class kSecClass的值表明一个通用的密码item笔者一般都传入的kSecClassGenericPassword

Demo(QiKeychain)相关代码

在Demo(QiKeychain)中,笔者对keychain相关使用的API进行了封装。获取 Demo(QiKeychain) GitHub地址: QiKeychain

注意: 笔者后来封装的代码,修改了保存操作的逻辑。

修改内容为: 在保存用户名密码的时候

-> 先在keychain中 查询 用户名是否存在

-> 若存在,就进行 更新 操作;

-> 若不存在就进行 保存 操作。

相应示意图(使用钥匙串存储网络密码)如下:

iOS 钥匙串的基本使用

以上所述就是小编给大家介绍的《iOS 钥匙串的基本使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing for Emotion

Designing for Emotion

Aarron Walter / Happy Cog / 2011-10-18 / USD 18.00

Make your users fall in love with your site via the precepts packed into this brief, charming book by MailChimp user experience design lead Aarron Walter. From classic psychology to case studies, high......一起来看看 《Designing for Emotion》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具