secItemCopyMatching 返回 nil 数据

2024-03-05

首先,我观看了 WWDC 2013 关于使用钥匙串保护秘密的会议。我想做一个基本的密码存储。看完了整个视频,但在视频的前 10 分钟找到了我需要的东西。这看起来很简单,但我不完全理解数据编码和检索是如何工作的。

问题:在 secItemCopyMatching 之后,我检查 NSData 对象以确保它在将其转换为 NSString 之前不为零。问题是,它总是为零。下面是我如何保存钥匙串条目或更新,然后是如何检索它。任何帮助和解释将非常感激。

更新(编辑): 果味极客,感谢您的回复。我已经使用 __bridge 更新了下面的代码。我的问题现在归结为,我是否正确存储和检索密码?我是两处都错了,还是只错了其中之一?我的 NSData 实例始终为零。我正在检查返回代码,并且我的 SecItemAdd 和 SecItemUpdate(当钥匙串条目存在时)工作正常。我似乎无法检索存储的数据(密码)的字符串值以将其与用户输入的密码进行比较。感谢帮助的男孩和女孩。这是我现在正在做的事情:

更新#2:(用 Fruity Geek 的答案和最终工作版本进行编辑。我的编辑仅包括对下面代码的更改。)

设置钥匙串条目:

NSData *secret = [_backupPassword dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
    (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
    (__bridge id)kSecAttrService: twServiceName,
    (__bridge id)kSecAttrAccount: twAccountName,
    (__bridge id)kSecValueData: secret,
};
OSStatus status =
    SecItemAdd((__bridge CFDictionaryRef)query, NULL);

if (status == errSecDuplicateItem) {
    // this item exists in the keychain already, update it
    query = @{
        (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
        (__bridge id)kSecAttrService: twServiceName,
        (__bridge id)kSecAttrAccount: twAccountName,
    };
    NSDictionary *changes = @{
        (__bridge id)kSecValueData: secret,
    };
    status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)changes);
}

从钥匙串中检索密码:

NSDictionary *query = @{
    (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
    (__bridge id)kSecAttrService: twServiceName,
    (__bridge id)kSecAttrAccount: twAccountName,
    (__bridge id)kSecReturnData: @YES,
};
NSData *data = NULL;
CFTypeRef dataTypeRef = (__bridge CFTypeRef)data;
OSStatus status =
    SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataTypeRef);

NSData *data = (__bridge NSData *)dataTypeRef;

NSString *passcode = @"none";
if (status == errSecSuccess) {
    // we found a keychain entry, set the passcode
    if (data)
        passcode = [NSString stringWithUTF8String:[data bytes]];
}

twServiceName 和 twAccountName 是静态 NSString。

正如我所说,我不太清楚我正在使用 __bridge 或 CFTypeRef 做什么。我浏览了苹果文档、这里的大量帖子和其他网站,但钥匙串和这些术语对我来说是全新的,我仍在试图弄清楚。希望这里有人能指出我的错误并帮助我理解。先谢谢您的帮助。

iOS 7 / Xcode 5


您不拥有任何 Core Foundation 对象(您没有创建或复制它们)并且您不想保留或释放它们,因此CFBridgingRelease and CFBridgingRetain是不正确的。使用(__bridge id)相反,每当你想转换为 Objective-C 对象时。

(__bridge id)kSecAttrService

什么时候应该使用 __bridge 与 CFBridgingRelease/CFBridgingRetain? https://stackoverflow.com/questions/18067108/when-should-you-use-bridge-vs-cfbridgingrelease-cfbridgingretain

您的数据变量和 dataTypeRef 是两个不同的指针。仅 dataTypeRef 填充了 SecItemCopyMatching 中的数据。将 CFTypeRef 转换为 NSDataafter它已由 SecItemCopyMatching 填充,因此您的数据并不总是为零

CFTypeRef dataTypeRef = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataTypeRef);
NSData *data = (__bridge NSData *)dataTypeRef;

您应该更仔细地查看所有 SecItem 函数调用返回的 OSStatus。有许多可能的返回代码不成功。在您的情况下,您正在检测 SecItemAdd 中的重复项目 - 然后将其更新为完全相同的项目(什么也不做)。相反,您应该首先尝试使用 SecItemCopyMatching 检索它。如果未找到匹配项,请使用 SecItemAdd。如果找到匹配项,请使用 SecItemUpdate。

Apple 的示例代码是terrible,不是为 ARC 编写的并且令人困惑,但它存在。特别是,writeToKeychain方法就是你所需要的。https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html#//apple_ref/doc/uid/TP30000897-CH208-SW1 https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html#//apple_ref/doc/uid/TP30000897-CH208-SW1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

secItemCopyMatching 返回 nil 数据 的相关文章

随机推荐

  • 使用 Java 为 Blogger API 验证自己的 Google 帐户

    我想编写一个将本地文件发布到 Google Blogger 的机器人 我将是唯一使用此应用程序的人 因此我不需要设置用户友好的身份验证例程 我花了一个晚上尝试进行设置 但仍然在处理 OAuth 请求方面遇到困难 我创建了一个新的 Googl
  • 现代 OpenGL 相当于 glBegin/glEnd 的是什么

    我正在为 OpenGL 构建一个图形 API 它基于基本的调用绘制图形样式 基本上 不是将数据存储到 GPU 中 并使用它的句柄调用它 而是提供信息来绘制每次更新应该绘制的内容 我知道它很慢 但它很简单 而且适用于非性能关键型应用程序 无论
  • 正则表达式:如何匹配不仅仅是数字的字符串

    是否可以编写一个正则表达式来匹配所有不匹配的字符串only包含数字 如果我们有这些字符串 abc a4c 4bc ab4 123 它应该匹配第一个 但不是最后一个 我尝试在 RegexBuddy 中摆弄前瞻之类的东西 但我似乎无法弄清楚 d
  • 如何在关系数据库中建模多语言实体

    如果我们要开发一个多语言应用程序 我们应该将翻译存储在资源文件 or the database 假设我们选择在数据库中进行 是否有一种标准方法来建模多语言实体关系模型 1 一张大翻译表 我们可以将所有翻译存储在一张表中并使用语言中立键为属性
  • Flexbox行:不根据内容增长? [复制]

    这个问题在这里已经有答案了 我有以下结构 我想了解为什么我的行不随其内部内容增长 row border solid red display flex flex direction row cell border solid green fl
  • 在 Maps API 浏览器上设置 HTTP Referrer 会导致 403 错误

    我对 HTTP Referrer 设置如何在 Google Maps API 浏览器密钥上工作感到困惑 我正在构建一个网页 以编程方式从 Google 地图请求图像 主要是 Google 地图街景图像 API 但也从 Javascript
  • spring-boot-starter-web 和 spring-boot-starter-webflux 不能一起工作吗?

    当我开始学习spring webflux 我对这个组件有疑问 我建立了一个简单的项目 使用maven来管理它 我添加了相关的依赖项spring boot starter web and spring boot starter webflux
  • Rufus 调度程序未登录生产环境

    我的 Rails 应用程序在初始化程序中使用 rufus scheduler 启动一个进程 这是初始化程序代码的精简版本 config logger isn t available here so we have to grab it fr
  • React 将 JQuery 代码应用于组件内的元素

    我有一个正在使用 React 的应用程序 我现在遇到一个问题 我正在尝试实施bootstrap 所见即所得 bootstrap3 所见即所得 https github com bootstrap wysiwyg bootstrap3 wys
  • 自动删除SQS队列

    有没有办法完全自动删除 SQS 队列 我有一个解决方案 其中服务器在启动时创建 SQS 并订阅 SNS 主题 然而 可能存在服务器崩溃且无法恢复的情况 在这种情况下 我会用另一台服务器替换该服务器 该服务器会在启动时创建自己的队列 现在之前
  • 对多个区域使用 Matcher.appendReplacement()

    java Matcher appendReplacement 方法 带有appendTail 应该让我将源文本转换为结果文本 同时替换所有出现的模式 伪语言的算法类似于 while Matcher find call Matcher app
  • 用于检查大网址列表中损坏链接的 Python 工具

    我有一个正在生产的搜索引擎 为大约 700 000 个网址提供服务 爬行是使用 Scrapy 完成的 所有蜘蛛程序都使用 DeltaFetch 进行调度 以便获取每日新链接 我面临的困难是处理损坏的链接 我很难找到一种定期扫描和删除损坏链接
  • 是否可以将 HTML/CSS 布局与 GWT 逻辑完全分离?

    我想让我们的 Web 开发人员继续使用纯 HTML 工作 并让开发人员编写 GWT 仅 Java 代码来编写其余的业务逻辑 有可能吗 有人尝试过在 GWT 环境中与 Web 开发人员一起工作吗 如何将 Web 开发人员纳入 GWT 开发流程
  • Typescript 实现接受多种类型输入的通用函数

    出于抽象目的 我需要实现一个接受不同类型输入的函数 type ContentA string type ContentB number type InputA name method a content ContentA type Inpu
  • 如何在 Visual Studio 中切换自动换行?

    Visual Studio NET 是否有办法打开和关闭自动换行 我习惯了 Eclipse 中的这个功能 它允许您右键单击并打开和关闭自动换行 这样当您有向右延伸的长行时 您不必向右和向左移动底部滚动条阅读你的代码 html http we
  • 从字符串在 node.js 中创建一个文本文件并将其作为响应进行流式传输

    我正在使用express js 我有一个字符串 Hello world 我希望用户点击 a href download Download a 用户应该下载包含文本的 Hello txt 而不是打开包含文本的选项卡 我已经四处寻找实现此目的的
  • 如何在 Xcode 4.5 上安装 iOS 4.3 模拟器?

    我通过 App Store 安装了 Xcode 4 5 它支持 iOS 5 1 和 6 0 但不支持 iOS 4 3 也无法在首选项的 下载 选项卡中下载 我尝试从另一台计算机上抓取它并将其放在这台计算机上 因为多米尼克 波拉达描述 htt
  • 如何根据字符数确定文件大小?

    在 Windows 上使用 java 和 jcifs 读取文件 我需要确定文件的大小 其中包含多字节以及 ASCII 字符 我怎样才能有效地实现它或java中的任何现有API Thanks 毫无疑问 要获得确切的字符数 您必须使用正确的编码
  • C# 或 VB 文档注释中的粗体还是斜体?

    有没有办法使用bold or italic里面的文档注释 就像是
  • secItemCopyMatching 返回 nil 数据

    首先 我观看了 WWDC 2013 关于使用钥匙串保护秘密的会议 我想做一个基本的密码存储 看完了整个视频 但在视频的前 10 分钟找到了我需要的东西 这看起来很简单 但我不完全理解数据编码和检索是如何工作的 问题 在 secItemCop