我正在为我们的 iPhone 应用程序实现 SSL 客户端身份验证,并使用应用程序钥匙串(keychain)来存储客户端身份(证书 + 私钥)。将项目添加到钥匙串(keychain)后,我在使用 SecItemCopyMatching 时得到了一些意想不到的结果。快速总结:我将一个 SecIdentityRef 添加到钥匙串(keychain),但 SecItemCopyMatching 之后发现了两个。让我从事实开始。
我在装有 iOS 4.3.5 的 iPod 上运行我的应用程序。
我有一个空的应用程序钥匙串(keychain)。
我的证书都是使用 openssl 创建的,并通过 PKCS#12 文件作为电子邮件附件部署到 iPod。 PKCS#12 文件包含:
- 客户证书
- 客户端 CA 证书(客户端证书的颁发者)
- 根 CA 证书(客户端 CA 证书的颁发者)
- 客户端证书的RSA私钥
SecPKCS12Import 成功导入文件,生成的字典内容如下:
- 一个“身份”
- 一个“信任”
- 一个“链”(持有上述三个证书的CFArray)
使用 SecItemAdd,我成功地将“身份”添加到钥匙串(keychain)。
接下来,我从字典中检索“链”数组并尝试添加证书。这样做时,第一个失败并出现错误 errSecDuplicateItem。我认为这是因为第一个证书是客户端证书,并且在我添加身份时它已经添加到钥匙串(keychain)中。其他两个证书添加无误。
现在,如果我返回并使用带有这些键/值对的 SecItemCopyMatching...
keys = {kSecClass, kSecReturnRef, kSecMatchLimit}
values = {kSecClassIdentity, kCFBooleanTrue, kSecMatchLimitAll}
...返回两个身份!此外,如果我检索每个 (SecIdentityCopyCertificate) 的证书,然后检索摘要 (SecCertificateCopySubjectSummary),我会看到这两个身份具有相同的证书!
最后,当我尝试从钥匙串(keychain) (SecItemDelete) 中清除身份时,第一次尝试成功,但第二次失败并返回 errSecItemNotFound。
从我一直在进行的所有谷歌搜索中可以清楚地看出,iOS 钥匙串(keychain)存在“问题”。但是,我还没有看到这方面的报道;我也没有看到任何相关的东西。
所以,我的问题:
- 我是否正确使用了 SecItemCopyMatching?
- 当使用 SecItemCopyMatching 在钥匙串(keychain)中查找身份时,它如何确定存在的身份?这是动态的,还是严格基于添加了多少 SecIdentityRef 项目?
- 这个问题可能与证书本身有关吗?请注意,尽管存在此问题,我仍然能够检索第一个身份和证书以响应 didReceiveAuthenticationChallenge。
如果需要,我可以发布代码和/或证书转储。
提前致谢
肯·克罗斯 西门子企业网络。
最佳答案
据我所知,您正在正确使用 SecItemCopyMatching
。
SecIdentityRef
项实际上并未存储在钥匙串(keychain)中;它们是为具有可用关联私钥的证书动态生成的。重复的身份确实很奇怪,并且可能表示框架问题——也许框架被第二组证书中的重复混淆了? (请务必在 bugreport.apple.com 提交错误!)当您重新启动应用程序时,重复的身份是否会消失?
另一方面,重复的身份不一定会导致任何实际问题。如果您担心您可能使用了错误的身份,只需要求 SecItemAdd
提供对它“创建”的身份的持久引用,并使用它来检索 SecIdentityRef
需要。
关于ios - SecItemCopyMatching 返回的 SecIdentityRef 项多于使用 SecItemAdd 添加的项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12305947/