Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes a keychain item unique (in iOS)?

People also ask

How does keychain work in IOS Swift?

Keychain: The keychain is a secure and encrypted storage place for sensitive data. You can think of it is a database of sensitive information. Keychain Item: This is a registry in the keychain. Item Class: You can think of a class as a template of information you want to store.

What is a keychain object?

A keychain (also key fob or keyring) is a small ring or chain of metal to which several keys can be attached. The length of a keychain allows an item to be used more easily than if connected directly to a keyring.

What is kSecAttrService?

A key whose value is a string indicating the item's service.

What is SecItemCopyMatching?

SecItemCopyMatching(_:_:) Returns one or more keychain items that match a search query, or copies attributes of specific keychain items.


The primary keys are as follows (derived from open source files from Apple, see Schema.m4, KeySchema.m4 and SecItem.cpp):

  • For a keychain item of class kSecClassGenericPassword, the primary key is the combination of kSecAttrAccount and kSecAttrService.
  • For a keychain item of class kSecClassInternetPassword, the primary key is the combination of kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort and kSecAttrPath.
  • For a keychain item of class kSecClassCertificate, the primary key is the combination of kSecAttrCertificateType, kSecAttrIssuer and kSecAttrSerialNumber.
  • For a keychain item of class kSecClassKey, the primary key is the combination of kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType, kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize, and the creator, start date and end date which are not exposed by SecItem yet.
  • For a keychain item of class kSecClassIdentity I haven't found info on the primary key fields in the open source files, but as an identity is the combination of a private key and a certificate, I assume the primary key is the combination of the primary key fields for kSecClassKey and kSecClassCertificate.

As each keychain item belongs to a keychain access group, it feels like the keychain access group (field kSecAttrAccessGroup) is an added field to all these primary keys.


I was hitting a bug the other day (on iOS 7.1) that is related to this question. I was using SecItemCopyMatching to read a kSecClassGenericPassword item and it kept returning errSecItemNotFound (-25300) even though kSecAttrAccessGroup, kSecAttrAccount and kSecAttrService were all matching the item in the keychain.

Eventually I figured out that kSecAttrAccessible didn't match. The value in the keychain held pdmn = dk (kSecAttrAccessibleAlways), but I was using kSecAttrAccessibleWhenUnlocked.

Of course this value is not needed in the first place for SecItemCopyMatching, but the OSStatus was not errSecParam nor errSecBadReq but just errSecItemNotFound (-25300) which made it a bit tricky to find.

For SecItemUpdate I have experienced the same issue but in this method even using the same kSecAttrAccessible in the query parameter didn't work. Only completely removing this attribute fixed it.

I hope this comment will save few precious debugging moments for some of you.


Answer given by @Tammo Freese seems to be correct (but not mentioning all primary keys). I was searching for some proof in the documentation. Finally found:

Apple Documentation mentioning primary keys for each class of secret (quote below):

The system considers an item to be a duplicate for a given keychain when that keychain already has an item of the same class with the same set of composite primary keys. Each class of keychain item has a different set of primary keys, although a few attributes are used in common across all classes. In particular, where applicable, kSecAttrSynchronizable and kSecAttrAccessGroup are part of the set of primary keys. The additional per-class primary keys are listed below:

  • For generic passwords, the primary keys include kSecAttrAccount and kSecAttrService.
  • For internet passwords, the primary keys include kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort, and kSecAttrPath.
  • For certificates, the primary keys include kSecAttrCertificateType, kSecAttrIssuer, and kSecAttrSerialNumber.
  • For key items, the primary keys include kSecAttrKeyClass, kSecAttrKeyType, kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeySizeInBits, and kSecAttrEffectiveKeySize.
  • For identity items, which are a certificate and a private key bundled together, the primary keys are the same as for a certificate. Because a private key may be certified more than once, the uniqueness of the certificate determines that of the identity.