gpt4 book ai didi

ios - 升级到 iOS 13 后,钥匙串(keychain)查询总是返回 errSecItemNotFound

转载 作者:行者123 更新时间:2023-12-04 13:30:36 25 4
gpt4 key购买 nike

我将密码存储到 iOS 钥匙串(keychain)中,然后检索它们以在我的应用程序上实现“记住我”(自动登录)功能。

我在 Security.framework 周围实现了自己的包装器功能( SecItemCopyMatching() 等),直到 iOS 12 之前它都像魅力一样工作。

现在我正在测试我的应用程序不会与即将推出的 iOS 13 中断,你瞧:

SecItemCopyMatching()总是返回 .errSecItemNotFound

...即使我之前已经存储了我正在查询的数据。

我的包装器是一个具有静态属性的类,可以方便地提供 kSecAttrService 的值。和 kSecAttrAccount组装查询字典时:

class LocalCredentialStore {

private static let serviceName: String = {
guard let name = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String else {
return "Unknown App"
}
return name
}()
private static let accountName = "Login Password"

// ...

我是 插入 使用如下代码将密码放入钥匙串(keychain)中:
/* 
- NOTE: protectWithPasscode is currently always FALSE, so the password
can later be retrieved programmatically, i.e. without user interaction.
*/
static func storePassword(_ password: String, protectWithPasscode: Bool, completion: (() -> Void)? = nil, failure: ((Error) -> Void)? = nil) {
// Encode payload:
guard let dataToStore = password.data(using: .utf8) else {
failure?(NSError(localizedDescription: ""))
return
}

// DELETE any previous entry:
self.deleteStoredPassword()

// INSERT new value:
let protection: CFTypeRef = protectWithPasscode ? kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly : kSecAttrAccessibleWhenUnlocked
let flags: SecAccessControlCreateFlags = protectWithPasscode ? .userPresence : []

guard let accessControl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
protection,
flags,
nil) else {
failure?(NSError(localizedDescription: ""))
return
}

let insertQuery: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccessControl: accessControl,
kSecValueData: dataToStore,
kSecUseAuthenticationUI: kSecUseAuthenticationUIAllow,
kSecAttrService: serviceName, // These two values identify the entry;
kSecAttrAccount: accountName // together they become the primary key in the Database.
]
let resultCode = SecItemAdd(insertQuery as CFDictionary, nil)

guard resultCode == errSecSuccess else {
failure?(NSError(localizedDescription: ""))
return
}
completion?()
}

...后来,我是 检索 密码:
static func loadPassword(completion: @escaping ((String?) -> Void)) {

// [1] Perform search on background thread:
DispatchQueue.global().async {
let selectQuery: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: serviceName,
kSecAttrAccount: accountName,
kSecReturnData: true,
kSecUseOperationPrompt: "Please authenticate"
]
var extractedData: CFTypeRef?
let result = SecItemCopyMatching(selectQuery, &extractedData)

// [2] Rendez-vous with the caller on the main thread:
DispatchQueue.main.async {
switch result {
case errSecSuccess:
guard let data = extractedData as? Data, let password = String(data: data, encoding: .utf8) else {
return completion(nil)
}
completion(password) // < SUCCESS

case errSecUserCanceled:
completion(nil)

case errSecAuthFailed:
completion(nil)

case errSecItemNotFound:
completion(nil)

default:
completion(nil)
}
}
}
}

(我不认为我用于任何一次调用的任何字典条目都有不适当的值......但也许我错过了一些刚刚发生的“通过”直到现在)

我设置了 a repository使用演示该问题的工作项目(Xcode 11 beta)。

密码存储始终成功;密码加载:
  • 成功 在 Xcode 10 - iOS 12(及更早版本)上,但
  • 失败 .errSecItemNotFound在 Xcode 11 - iOS 13 上。


  • 更新:我无法在设备上重现该问题,只能在模拟器上重现。在设备上,已成功检索存储的密码。
    这可能是适用于 x86 平台的 iOS 13 模拟器和/或 iOS 13 SDK 的错误或限制。

    更新 2:如果有人想出一种替代方法以某种方式解决该问题(无论是通过设计还是利用 Apple 的某些监督),我会接受它作为答案。

    最佳答案

    我遇到了类似的问题,我得到了 errSecItemNotFound任何与钥匙串(keychain)相关的操作,但 仅限 在模拟器上。在真实设备上它是完美的,我已经在不同的模拟器上使用最新的 Xcode(beta、GM、stable)进行了测试,而让我感到困难的是 iOS 13 的。

    问题是我使用的是 kSecClassKey在查询属性 kSecClass ,但没有用于生成主键的“必需”值(查看哪些类与哪些值 here ):

  • kSecAttrApplicationLabel
  • kSecAttrApplicationTag
  • kSecAttrKeyType
  • kSecAttrKeySizeInBits
  • kSecAttrEffectiveKeySize

  • 帮助的是选择 kSecClassGenericPassword对于 kSecClass 提供生成主键的“必需”值:
  • kSecAttrAccount
  • kSecAttrService

  • here关于 kSecClass 类型的更多信息以及它们应该附带的其他属性。

    我通过启动一个新的 iOS 13 项目并复制我们应用程序中使用的钥匙串(keychain)包装器得出了这个结论,正如预期的那样,它不起作用,所以我找到了这个关于使用钥匙串(keychain)的可爱指南 here并试用了他们的包装器 毫不奇怪工作,然后逐行比较我的实现与他们的实现。

    此问题已在雷达中报告: http://openradar.appspot.com/7251207

    希望这可以帮助。

    关于ios - 升级到 iOS 13 后,钥匙串(keychain)查询总是返回 errSecItemNotFound,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56700680/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com