Cannot get symmetric key from keychain

Hello,


Try to create and retreive a symmetric key from keychain :


add the key

-----------------------------------

let key = Data.init(repeating: 0xee, count: 32)

let name = "test"

let attributes = [kSecAttrKeyType: kSecAttrKeyTypeAES, kSecAttrKeySizeInBits: NSNumber.init(value: 256)] as CFDictionary

var error: Unmanaged<CFError>?

let secKey = SecKeyCreateFromData(attributes, key as CFData, &error)


let addquery = [kSecClass: kSecClassKey,

kSecAttrKeyClass: kSecAttrKeyClassSymmetric,

kSecAttrLabel: name,

kSecValueRef: secKey!] as CFDictionary

let status = SecItemAdd(addquery as CFDictionary, nil)

if status != errSecSuccess

{

print(SecCopyErrorMessageString(status, nil)!)

}

-----------------------------------


The keychain item is created


Get the key

-----------------------------------

let name = "test"


let getquery = [kSecClass: kSecClassKey,

kSecAttrKeyClass: kSecAttrKeyClassSymmetric,

kSecAttrLabel: name] as [CFString : Any]

var secKey: CFTypeRef?

let status = SecItemCopyMatching(getquery as CFDictionary, &secKey)

if status == errSecSuccess

{

if let dic = SecKeyCopyAttributes(secKey as! SecKey) as? [CFString: Any]

{

if let key = dic[kSecValueData] { print("Ok") }

else { print("Cannot get the key") }

}

else

{

print("Error retrieving dictionnary")

}

}

else

{

print(SecCopyErrorMessageString(status, nil)!)

}

-----------------------------------


If the key is added and retreive in the same process it works. The number of elements in the dic is 21.

But if later (in another process) i try to get the key stored in keychain i get the dictionnary but not the key. The number of elements in the dic is 20 (kSecValueData is missing).


What parameters are missing to get the key ?


Thank you

Replies

But if later (in another process) i try to get the key stored in keychain

What’s the relationship between these processes?

Keep in mind that the Mac has two different keychain implementations, the original file-based keychain and the new iOS-style keychain. Sharing items between programs is quite tricky in the file-based keychain.

Share and Enjoy

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

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

> What’s the relationship between these processes?


Nothing, just 2 debug run.


i run SecItemAdd and SecItemCopyMatching, it works (i get the key)

i run only SecItemCopyMatching and i don't get the key (kSecValueData missing). but the key is stored.


i do that in debug mode.

I fact the code is correct. I was simply comment some lines (add the key )between 2 runs to avoid errors in debug mode.

By simply modify the code it triggers the non-availability of the key. For example reverse 2 lines :

change :
 
Code Block
kSecAttrKeyClass: kSecAttrKeyClassSymmetric,
kSecAttrLabel: name] as [CFString : Any]

by

Code Block
kSecAttrLabel: name] as [CFString : Any],
kSecAttrKeyClass: kSecAttrKeyClassSymmetric


Which is the same thing.
By doing that the key is more available.(no value for kSecValueData)

The same thing happened with kSecClassGenericPassword but a prompt ask the keychain password.
The problem is that for symmetric key there is no prompt and the key is not accessible (no value for kSecValueData)

Loosing the key by that way is too dangerous.

How can i get the key stored ?

Note: This does not happened with playground.
You can modify the code at will and the key is always retrieved.

Thank you.