objective c - 什么使得钥匙串项目独一无二(在iOS中)?

我的问题涉及iOS(iPhone,iPad,...)中的钥匙串。 我认为(但不确定)Mac OS X下的钥匙串的实现会以相同的答案提出同样的问题。


iOS提供五种类型(类)的钥匙串项。 您必须为密钥kSecClass选择这五个值中的一个来确定类型:

kSecClassGenericPassword  used to store a generic password
kSecClassInternetPassword used to store an internet password
kSecClassCertificate      used to store a certificate
kSecClassKey              used to store a kryptographic key
kSecClassIdentity         used to store an identity (certificate + private key)

经过长时间阅读苹果文档,博客和论坛条目,我发现kSecClass类型的钥匙串项从属性kSecClassGenericPassword,kSecAttrServicekSecClassGenericPassword获得其唯一性。

如果请求1中的这三个属性与请求2中的相同,则无论其他任何属性如何,您都会收到相同的通用密码keychain项。 如果此属性中的一个(或两个或全部)更改其值,则会获得不同的项目。

但是kSecClass仅适用于kSecClassGenericPassword类型的物品,因此它不能成为"唯一键的一部分" 任何其他类型的项目,似乎没有文件明确指出哪些属性唯一确定钥匙串项目。

类" KeychainItemWrapper"中的示例代码 " GenericKeychain" 使用属性kSecClass使项目唯一,但这是一个错误。 此示例中的两个条目仅存储为两个不同的条目,因为它们的kSecClassGenericPassword不同(一个设置了访问组,另一个允许它自由)。 如果您尝试使用Apple的kSecAttrService添加没有访问组的第二个密码,则会失败。

那么,请回答我的问题:

  • 这是真的,kSecClass,kSecClassGenericPasswordkSecAttrService的组合是"唯一键" 一个钥匙串项目的kSecClass是kSecClassGenericPassword
  • 如果kSecClass不是kSecClassGenericPassword,哪个属性会使钥匙串项目独一无二?
Hubert Schölnast asked 2019-08-13T05:01:48Z
3个解决方案
152 votes

主键如下(从Apple的开源文件派生,请参阅Schema.m4,KeySchema.m4和SecItem.cpp):

  • 对于类kSecClassKey的钥匙串项,主键是组合kSecAttrApplicationLabelkSecAttrApplicationTag
  • 对于类kSecClassKey的钥匙串项,主键是kSecAttrApplicationLabel,kSecAttrApplicationTag,kSecAttrSerialNumber,kSecAttrProtocol,kSecAttrAuthenticationType,kSecAttrPortkSecAttrPath的组合。
  • 对于类kSecClassKey的钥匙串项,主键是kSecAttrApplicationLabel,kSecAttrApplicationTagkSecAttrSerialNumber的组合。
  • 对于类kSecClassKey的钥匙串项目,主键是kSecAttrApplicationLabel,kSecAttrApplicationTag,kSecAttrAccessGroup的组合,kSecClassKey,kSecClassCertificate,以及SecItem尚未公开的创建者,开始日期和结束日期。
  • 对于类kSecAttrAccessGroup的钥匙串项目,我还没有找到开源文件中主键字段的信息,但由于标识是私钥和证书的组合,我假设主键是组合 kSecClassKeykSecClassCertificate的主键字段。

由于每个钥匙串项属于钥匙串访问组,感觉钥匙串访问组(字段kSecAttrAccessGroup)是所有这些主键的添加字段。

Tammo Freese answered 2019-08-13T05:02:50Z
8 votes

我前几天(在iOS 7.1上)遇到了一个与此问题相关的错误。 我正在使用SecItemUpdate阅读kSecAttrAccessible项目,它仍然保持返回query(-25300),即使errSecBadReq,errSecItemNotFoundkSecAttrService都与钥匙串中的项目相匹配。

最终我发现SecItemUpdate并不匹配。 钥匙串中的值持有pdmn = dk(kSecAttrAccessible),但我使用的是query

当然这个值不是首先需要SecItemUpdate,但kSecAttrAccessible不是query也不是errSecBadReq而是errSecItemNotFound(-25300)这使得它有点难以找到。

对于SecItemUpdate我遇到了同样的问题,但在这种方法中,即使在query参数中使用相同的kSecAttrAccessible也无法正常工作。 只有完全删除此属性才能修复它。

我希望这个评论能为你们中的一些人节省一些宝贵的调试时间。

izik lisbon answered 2019-08-13T05:03:51Z
2 votes

@Tammo Freese给出的答案似乎是正确的(但没有提到所有主键)。 我在文档中搜索一些证据。 终于找到了:

Apple文档提到了每类秘密的主键(引用如下):

当该钥匙串已经具有具有相同复合主键集的相同类的项时,系统将该项视为给定钥匙串的副本。 每个类的keychain项都有一组不同的主键,尽管在所有类中共同使用了一些属性。 特别是,在适用的情况下,kSecAttrSynchronizable和kSecAttrAccessGroup是主键集的一部分。 下面列出了每个类的其他主键:

  • 对于通用密码,主键包括kSecAttrAccount和  kSecAttrService。
  • 对于Internet密码,主键包括kSecAttrAccount,   kSecAttrSecurityDomain,kSecAttrServer,kSecAttrProtocol,   kSecAttrAuthenticationType,kSecAttrPort和kSecAttrPath。
  • 对于证书,主键包括kSecAttrCertificateType,   kSecAttrIssuer和kSecAttrSerialNumber。
  • 对于关键项,主键包括kSecAttrKeyClass,   kSecAttrKeyType,kSecAttrApplicationLabel,kSecAttrApplicationTag,   kSecAttrKeySizeInBits和kSecAttrEffectiveKeySize。
  • 对于身份项,它是证书和捆绑的私钥   同时,主键与证书相同。 因为   私钥可能不止一次被认证,其独特性   证书确定身份。
Julian Król answered 2019-08-13T05:05:14Z
translate from https://stackoverflow.com:/questions/11614047/what-makes-a-keychain-item-unique-in-ios