SecItemAdd()与kSecAttrAccessibleWhenUnlocked成功,但与kSecAttrAccessibleWhenUnlockedThisDeviceOnly失败 [英] SecItemAdd() Succeeds with kSecAttrAccessibleWhenUnlocked But Fails with kSecAttrAccessibleWhenUnlockedThisDeviceOnly

查看:219
本文介绍了SecItemAdd()与kSecAttrAccessibleWhenUnlocked成功,但与kSecAttrAccessibleWhenUnlockedThisDeviceOnly失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止的故事

四个月前,我发布了这个问题,因为升级到iOS 13破坏了我与钥匙串相关的代码. /p>

我的代码使用类kSecClassGenericPassword和访问属性kSecAttrAccessibleWhenUnlocked将用户的密码存储在钥匙串中.正如我对这个问题的回答所解释的那样,通过稍微清理一下查询字典,我终于使我的代码也可以在iOS 13上使用.

当前问题

几周前,我被要求禁用备份密码数据以增强安全性,因此我将访问属性更改为kSecAttrAccessibleWhenUnlockedThisDeviceOnly(与kSecAttrAccessibleWhenUnlocked不同,备份期间将钥匙串传输到另一台设备.

现在,我的代码失败,用户每次都必须输入密码.(在iOS 13.0,iPhone 8 Plus上进行了测试)

当用户使用密码登录时,我的代码首先使用SecItemDelete()删除任何以前存储的密码,然后继续使用SecItemMatch()存储输入的密码.

由于将访问属性更改为kSecAttrAccessibleWhenUnlockedThisDeviceOnlySecItemDelete()使用errSecItemNotFound成功"(即,无删除内容"),因此但是SecItemAdd()失败,并显示errSecDuplicateItem

注意,这不是尝试使用kSecAttrAccessibleWhenUnlockedThisDeviceOnly检索以前用kSecAttrAccessibleWhenUnlocked存储的密码的问题(即,用于存储和加载的不同查询字典);我从设备上删除了该应用,并从一开始就尝试使用新代码,而SecItemAdd()总是失败.

发生了什么事?

解决方案

我认为您已经知道了,但是为了完整性:

请注意,这不是尝试使用kSecAttrAccessibleWhenUnlockedThisDeviceOnly检索先前使用kSecAttrAccessibleWhenUnlocked存储的密码的问题(即,用于存储和加载的不同查询字典);我从设备上删除了该应用,并从一开始就尝试使用新代码,而SecItemAdd()始终会失败.

这正是您正在发生的事情.钥匙串内容可以在应用删除后重新安装.要解决此问题,您需要提出一种迁移策略,该策略将删除使用相同主键但访问控制设置不同保存的项目,然后再尝试保存新项目

The Story So Far

Four months ago, I posted this question because the upgrade to iOS 13 was breaking my keychain-related code.

My code stores the user's password in the keychain using class kSecClassGenericPassword and access attribute kSecAttrAccessibleWhenUnlocked. As explained in my own answer to that question, I finally got my code to work also on iOS 13 by cleaning up the query dictionaries a bit.

The Current Problem

A few weeks ago, I was asked to disable backing up of the password data to enhance security, so I changed the access attribute to kSecAttrAccessibleWhenUnlockedThisDeviceOnly (unlike kSecAttrAccessibleWhenUnlocked, the password in the keychain is not transferred to another device during backups).

Now, my code fails and the user has to enter their password every time. (tested on iOS 13.0, iPhone 8 Plus)

When the user logs in using their password, my code first deletes any previously stored password using SecItemDelete(), and then proceeds to store the entered password using SecItemMatch().

Since changing the access attribute to kSecAttrAccessibleWhenUnlockedThisDeviceOnly, SecItemDelete() "succeeds" with errSecItemNotFound (i.e., "Nothing to delete"), but SecItemAdd() fails with errSecDuplicateItem!

Note, this isn't an issue of trying to retrieve a password previously stored with kSecAttrAccessibleWhenUnlocked using kSecAttrAccessibleWhenUnlockedThisDeviceOnly (i.e., different query dictionaries for store and load); I deleted the app from the device and tried from the start with the new code, and SecItemAdd() always fails.

What's Going On?

解决方案

I assume you've already figured that out, but for the sake of completeness:

Note, this isn't an issue of trying to retrieve a password previously stored with kSecAttrAccessibleWhenUnlocked using kSecAttrAccessibleWhenUnlockedThisDeviceOnly (i.e., different query dictionaries for store and load); I deleted the app from the device and tried from the start with the new code, and SecItemAdd() always fails.

This is exactly what is happening to you. Keychain contents survive app deletion and re-install. To fix the issue you need to come up with a migration strategy that will remove items saved with the same primary keys, but different access control setting before trying to save new ones

这篇关于SecItemAdd()与kSecAttrAccessibleWhenUnlocked成功,但与kSecAttrAccessibleWhenUnlockedThisDeviceOnly失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆