【问题标题】:How to obtain a digital identity from the keychain?如何从钥匙串中获取数字身份?
【发布时间】:2019-11-14 22:42:42
【问题描述】:

我正在学习 Apple 的教程:https://developer.apple.com/documentation/security/certificate_key_and_trust_services/certificates/storing_a_certificate_in_the_keychain

https://developer.apple.com/documentation/security/certificate_key_and_trust_services/identities/storing_an_identity_in_the_keychain

关于如何从钥匙串中存储和检索身份。

存储身份似乎工作正常,返回errSecSuccess。但是,当尝试获取任何身份时,我会返回 errSecItemNotFound(或 -25300)。

即使转储钥匙串也无法按预期工作;成功添加身份后,SecItemCopyMatching 仍然返回errSecItemNotFound

请参阅以下与文档中提供的摘录非常匹配的代码:

// Store the digital identity in the keychain:
let addQuery: [String : Any] = [kSecClass as String: kSecClassIdentity,
                                kSecValueRef as String: identity,
                                kSecAttrLabel as String: "myid"]

guard SecItemAdd(addQuery as CFDictionary, nil) == errSecSuccess else {
    print("Could not store identity in keychain")
    return false
}

// Obtain the digital identity from the keychain:
let getQuery: [String : Any] = [kSecClass as String: kSecClassIdentity,
                                kSecAttrLabel as String: "myid",
                                kSecReturnRef as String: kCFBooleanTrue!]
var item: CFTypeRef?
let status = SecItemCopyMatching(getQuery as CFDictionary, &item)
guard status == errSecSuccess else {
    print("Could not find identity in keychain, OSerror: \(status)") // <---- -25300
    return false
}

let localIdentity = item as! SecIdentity

// [...]

为了完整起见,这就是我“转储”钥匙串(至少是身份)的方式:

let getQuery: [String : Any] = [kSecClass as String : secClass,
                                kSecReturnData as String  : kCFBooleanTrue!,
                                kSecReturnAttributes as String : kCFBooleanTrue!,
                                kSecReturnRef as String : kCFBooleanTrue!,
                                kSecMatchLimit as String : kSecMatchLimitAll]
var items: CFTypeRef?
let status = SecItemCopyMatching(getQuery as CFDictionary, &items) // <--- again, status = -25300

缺少什么?

我多次浏览了这些文档。将物品存放在钥匙串中需要一些时间吗?如果是这样,Apple 提供的示例是否提到了这一点?

为什么我在存储项目时收到errSecSuccess,但之后却无法让我立即阅读该项目?

我也在真实设备上进行测试。

【问题讨论】:

  • 对不起.. 我没有弄清楚我的意思.. 创建identity 的代码在哪里,为什么它是一个字符串?
  • 不用担心;身份是从 p12 文件中导入的。然而,我认为这应该无关紧要,因为 SecItemAdd 返回了 errSecSuccess。你怎么会认为它是一个字符串? @Brandon 这是一个秘密身份。
  • 从钥匙串中检索证书时,需要使用kSecClass: kSecClassCertificate
  • 啊,你确定吗?苹果文档说的有点不同。我想从钥匙串中获得的不是证书,而是数字身份。这既是证书又是私钥。这是为什么?不过我会试试的。 @布兰登
  • 那么我很困惑,因为代码显示 "mycert" 所以我认为这是一个错字,您将其存储为身份而不是证书。

标签: ios swift security keychain ios13


【解决方案1】:

我终于自己找到了答案。

在身份上使用标签很棘手,因为身份不是作为原子项目存储在钥匙串中,而是作为单独的私钥和证书存储,并且这些项目以不同的方式使用标签。

https://forums.developer.apple.com/thread/98029

即:

  1. 将身份添加到钥匙串时将kSecReturnPersistentRef 传递给SecItemAdd
  2. 将持久引用保存在任何地方
  3. 稍后,当您需要返回身份时,使用该持久引用调用 SecItemCopyMatching

这是有道理的,我终于能够以这种方式解决我的问题。

【讨论】:

    猜你喜欢
    • 2019-01-04
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多