Unique RSA KeyChain item

During the creation of several key items, I noticed that there are several 'label' or 'tag' options. I did some investigation and I found three different, interesting, values.


kSecAttrApplicationTag - A key whose value indicates the item's private tag.

kSecAttrApplicationLabel - A key whose value indicates the item's application label.

kSecAttrLabel - A key whose value is a string indicating the item's label.


I read that the kSecAttrLabel is "human readable data". But what exactly is meant with the description of the kSecAttrApplicationTag? What exactly is the private tag.


Another question I have is, how can I uniquely identify a key. Say I want to have a single key to encrypt a specific file, how would I go about doing so? Theoretically, I could set the kSecAttrApplicationLabel, as this has to be a unique value, meaing if I were to set the value to "com.app.appname.someidentifier".data(using: .utf8)! an error would occur if the key would (accidentally) be created again (which is what I want to prevent). However the discussion says "in particular, for keys of class

kSecAttrKeyClassPublic
and
kSecAttrKeyClassPrivate
, the value of this attribute is the hash of the public key", and RSA keys do have the public/private class, so the value would no longer be the hash of the public key. Am I actually allowed to overwrite the kSecAttrApplicationLabel? If not, do I have to check if a key for kSecAttrApplicationTag/kSecAttrLabel already exists and delete it first, before adding a new 'unique' key?


Thanks in advance!

Accepted Reply

As I read that the errSecDuplicateItem will never be triggered, as the

kSecAttrApplicationLabel
will differ each time for a random key

Correct. As mentioned in the post I referenced earlier, the expected value for

kSecAttrApplicationLabel
for an asymmetric key is the public key hash. If you’re generating a new key pair, the publish key hash is essentially a large random number, and thus this attribute will be globally unique.

the uniqueness of the key relies on the entire dictionary/property list and not on a single property, correct?

Not the entire attribute list, but the class-specific list of attributes given in the

errSecDuplicateItem
documentation.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

I struggle to remember this info myself, so a while back I posted a summary of their meaning for the benefit of Future Quinn™. Please read that through and then post a follow-up here if there’s still anything unclear.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Add a Comment

Thanks for your reply. I do read that the kSecApplicationTag "Is a component of key uniqueness". However, how does this component work towards key uniqueness? See the example below


let keyAttributes: [String: Any] = [
    String(kSecAttrKeyType)         : kSecAttrKeyTypeRSA,
    String(kSecAttrKeySizeInBits)   : 4096,
    String(kSecAttrApplicationTag)  : kKeyTag,
    String(kSecPrivateKeyAttrs)     :
    [
        String(kSecAttrIsPermanent)     : true
    ]
]
var error: Unmanaged? = nil
let privateKey = SecKeyCreateRandomKey(keyAttributes as CFDictionary, &error)


The kKeyTag is a constant, it does not change. However, everytime I trigger this block of code, another RSA key gets added to the KeyChain with the kKeyTag, in other words, the error object remains nill and no errSecDuplicateItem is created. Therefore, I don't believe the kKeyTag works towards key uniqueness, as I can not unique identify the key via the tag. Can you elaborate further?

You only get

errSecDuplicateItem
if every attribute that contributes to key uniqueness is the same. You can find a list of such attributes, which is different for each keychain items class, in the
errSecDuplicateItem
documentation.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Ah, right. However, question remains, unless my assumption of earlier is correct:


"do I have to check if a key for kSecAttrApplicationTag/kSecAttrLabel already exists and delete it first, before adding a new 'unique' key?"


As I read that the errSecDuplicateItem will never be triggered, as the kSecAttrApplicationLabel will differ each time for a random key, thus meaning it's technically not a duplicate. In other words, the uniqueness of the key relies on the entire dictionary/property list and not on a single property, correct?

As I read that the errSecDuplicateItem will never be triggered, as the

kSecAttrApplicationLabel
will differ each time for a random key

Correct. As mentioned in the post I referenced earlier, the expected value for

kSecAttrApplicationLabel
for an asymmetric key is the public key hash. If you’re generating a new key pair, the publish key hash is essentially a large random number, and thus this attribute will be globally unique.

the uniqueness of the key relies on the entire dictionary/property list and not on a single property, correct?

Not the entire attribute list, but the class-specific list of attributes given in the

errSecDuplicateItem
documentation.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"