美文网首页
钥匙串的基本使用

钥匙串的基本使用

作者: Lucky_Man | 来源:发表于2019-02-17 20:43 被阅读0次

前言
项目中有时会需要存储敏感信息(如密码、密钥等),苹果官方提供了一种存储机制--钥匙串(keychain)
keychain是一种存储在硬盘上的加密的数据库。这个可能是卸载App后,keychain信息还在的原因。
keychain适合存储 较小的数据量不超过上千字节或上兆字节)的内容。
笔者做了一个关于keychain的增、删、改、查的Demo(QiKeychain),给大家介绍下keychain的基本使用。

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


keychain存储密码密钥证书标识日志等

Demo(QiKeychain)解读

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

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

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

  • 存储用户名 “QiShare”,密码:1234;
  • 查询用户名为“QiShare”的密码,显示密码为:1234;
  • 修改用户名“QiShare”的密码为“123456”;
    • 查询“QiShare”的密码,显示为“123456”;
  • 把“QiShare”从keychain中删除。
keychainGif.gif

keychain基本使用API

keychain有四个常用的API,用于增、删、改、查keychain中的数据。
keychain中的数据子项是以item的形式存在的。
举个例子:就存储用户名、密码的情景来说,每个item包含存储的用户名和密码及其他属性信息,keychain中包含多个用户名和密码的item。

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


把数据和属性存储到keychain中
  • 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中`查询`用户名是否存在
  -> 若存在,就进行`更新`操作;
  -> 若不存在就进行`保存`操作。

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


使用钥匙串存储网络密码

参考学习地址

相关文章

  • 钥匙串的基本使用

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

  • iOS 钥匙串的基本使用

    级别: ★☆☆☆☆标签:「钥匙串」「keychain」「iOS」作者: WYW审校: QiShare团队 前言 ...

  • 钥匙串使用

    iOS提供一种安全的存储数据的方式,就是钥匙串,想要在app中使用钥匙串,首先要开启钥匙串访问的功能,即在app ...

  • 钥匙串

    钥匙串 苹果的"生态圈",钥匙串访问,使用 AES 256 加密算法,能够保证用户密码的安全 钥匙串访问SDK,是...

  • 钥匙串

    钥匙串 苹果的"生态圈",钥匙串访问,使用 AES 256 加密算法,能够保证用户密码的安全 钥匙串访问SDK,是...

  • iOS安全-钥匙串服务(iOS Keychain Service

    本文描述iOS中基本的钥匙串访问,内容整理于苹果官方文档。本文主要讲述以下内容: 钥匙串中添加一个条目 钥匙串中查...

  • 【OC】钥匙串使用

    钥匙串可存储少量数据,常用于App删除后数据依然存储在本地的需求 1.增(存储) 2.查 3.改 4.删 Demo...

  • KeyChain钥匙串的使用

    相信在我们存储一些数据的时候都会遇到一些苦恼,如果应用一旦被用户删除,那么设备中的信息就会被清除掉。此时,keyc...

  • iOS:获取iOS设备唯一标识符:IDFV+KeyChain(钥

    综上所述,一般使用 IDFV配合 keyChain(钥匙串)使用:

  • mac问题:想使用本地项目钥匙串

    Mac中,始终出现弹窗,显示: xxx 想使用本地项目钥匙串,请输入钥匙串密码 Finder-》前往-》前往文件夹...

网友评论

      本文标题:钥匙串的基本使用

      本文链接:https://www.haomeiwen.com/subject/tqbgeqtx.html