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


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

keychain基本使用API

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

下图(把数据和属性存储到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 Services
  • SAMKeychain

小编微信:可加并拉入《QiShare技术交流群》。

关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
iOS 自定义拖拽式控件:QiDragView
iOS 自定义卡片式控件:QiCardView
iOS Wireshark抓包
iOS Charles抓包
初探TCP
IP、UDP初探
奇舞周刊

iOS 钥匙串的基本使用相关推荐

  1. iOS钥匙串三种提取方案【iOS加密备份】【keychain_dumper】【frida-objection】

    iOS钥匙串(keychain)是iOS操作系统提供的一种安全存储机制,用于存储用户的敏感信息(如密码等).钥匙串管理器可以在任何应用和扩展中安全地存储和访问用户的敏感信息,而不会被其他应用的访问或破 ...

  2. iOS钥匙串KeyChain相关参数的说明

    一.Keychain 基础 根据苹果的介绍,iOS设备中的Keychain是一个安全的存储容器,可以用来为不同应用保存敏感信息比如用户名,密码,网络密码,认证令牌.苹果自己用keychain来保存Wi ...

  3. iOS钥匙串Keychain浅析

    根据苹果的介绍,iOS设备中的Keychain是一个安全的存储容器,可以用来为不同应用保存敏感信息比如用户名,密码,网络密码,认证令牌.苹果自己用keychain来保存WiFi密码,VPN凭证等.它是 ...

  4. ios 凭据验证_iOS应用SSL .p12身份验证 – 证书错误(-9825)

    更新 编辑2/6/14: 我创建了一个本地Apache Tomcat服务器来测试带有证书身份验证的SSL.我成功了!使用下面的两种方法,一切都按预期工作. (MKNetworkKit和自定义代码).虽 ...

  5. iOS开发之极光推送JPush

    JPush介绍 JPush可以轻松地通过极光推送完成运营推送工作同时支持自定义消息.富媒体消息.应用内提醒消息.短视频消息和围栏消息等9种类型,满足开发者在各类应用场景下运营所需9种消息类型. 配置i ...

  6. 加密数据储存工具:Keychain 介绍与使用

    一.简介 iOS 设备中的 keychain 为用户安全储存一些敏感数据,比如用户密码,认证令牌等.苹果自己用 keychain 来保存 Wi-Fi 密码,证书等等.Keychain 内的数据可以通过 ...

  7. 黑客利用本地新闻站点在iPhone上安装间谍软件

    iPhone iOS间谍软件,一项新发现的黑客"水坑攻击"针对香港的苹果iPhone用户,利用恶意网站链接诱使他们在设备上安装间谍软件. 根据国内知名网络黑客安全组织东方联盟和卡巴 ...

  8. 《全民挂机》 源码解析 一

    源码来自9miao 本人技术有限,大家共同学习,抛砖引玉,加群讨论 交流群: 422209275 2.140.0版本的全民挂机 概述: 基本目录结构: Code_Client  (客户端 具体游戏相关 ...

  9. 极客必知:iPhone备份番外篇

    如果你长期混迹于密码破解的第一线,那么就非常清楚破解相同内容的不同文件格式对破解的速度的影响是非常大的.例如,破解保护RAR文档密码所需的时间是破解具有相同内容的ZIP文档密码的十倍,而破解保存在Of ...

最新文章

  1. PHP之mb_internal_encoding使用
  2. LeetCode - Reorder List
  3. 爬虫 - POJ题目信息
  4. 四面体的表面积_为了解释南北两极海陆的分布,科学家提出了一个“四面体”的观点...
  5. IDEA导入Eclipse项目
  6. c++ array学习
  7. 如何使用fio模拟线上环境
  8. 前端学习(892):bom概述
  9. lstm中look_back的大小选择_使用PyTorch手写代码从头构建LSTM,更深度的理解其工作原理
  10. 相亲交友源码中,音频AAC解码的实现代码
  11. 中国工业企业数据库stata处理
  12. 【github】-MM-Wiki初体验
  13. 计算机辅助设计rhino试题,计算机辅助设计基础期末复习试题(完整版).doc
  14. 数据库课程设计:医院信息管理系统(pycharm+MySQL)
  15. DirectX示例翻译和解析StateManager Sample
  16. 舍得酒业前三季营收净利双增背后 低档酒提速拖累Q3毛利率
  17. 用Java编程开发“六级单词强化记忆”游戏
  18. circos 可视化手册-line plot 篇
  19. 计算机进入pe快捷键,U盘启动快捷键大全(附U盘启动必杀技)
  20. AI 智能写情诗、藏头诗

热门文章

  1. css中变量_CSS中的变量
  2. BBIAB的完整形式是什么?
  3. AMUL的完整形式是什么?
  4. observable_Java Observable countObservers()方法与示例
  5. librtmp分析(发送数据包处理)
  6. 汇编语言-012(扩展加法指令ADC、带借位减法指令SBB、执行加法后进行ASCII调整指令、AAS 、AAM、AAD 、DAA指令将和数转成压缩十进制格式)
  7. HDU 2544 最短路(各种最短路算法的实现)
  8. 172. 阶乘后的零 golang
  9. task_struct结构体查找
  10. mysql 学习笔记04 insert与update语句