Hi all,
I've been working on implementing CryptoKit in my app, and I seem to have run into a wall where I can't get the generated SymmetricKey to be stored in the keychain. Here is the code I've written:
I was also attempting to add the following attributes to the keychain query (but commented them out because I was attempting to troubleshoot this issue)
I've tried storing the key as both a a kSecClassGenericPassword and a kSecClassKey, and it returns the same -50 ("One or more parameters passed to a function were not valid.") error. I've tried storing the key as both Data and the SymmetricKey iteself, and I have tried storing the ApplicationTag as both a String and as Data. Neither of these resolve the issue. I'm hoping someone has some ideas on what I'm missing here.
I've been following the instructions listed here: https://developer.apple.com/documentation/cryptokit/storing_cryptokit_keys_in_the_keychain
Here is my code to convert to a rawRepresentation (the code supplied in the CryptoKit Keys in the Keychain article didn't compile unfortunately).
Thanks in advance for the help.
I've been working on implementing CryptoKit in my app, and I seem to have run into a wall where I can't get the generated SymmetricKey to be stored in the keychain. Here is the code I've written:
Code Block swift static func makeAndStoreKey(name: String) throws -> SymmetricKey? { let nameData = name.data(using: .utf8) let symmetricKey = SymmetricKey(size: .bits256) let query = [kSecClass: kSecClassGenericPassword, kSecAttrApplicationTag: nameData!, kSecValueRef: symmetricKey.rawRepresentation] as [String: Any] let status = SecItemAdd(query as CFDictionary, nil) guard status == errSecSuccess else { throw KeyStoreError("Unable to store item: \(status.message)") } return symmetricKey } static func loadKey(name: String) throws -> SymmetricKey? { let nameData = name.data(using: .utf8) let query = [kSecClass: kSecClassGenericPassword, kSecAttrApplicationTag: nameData!, kSecReturnRef: true] as [String: Any] var item: CFTypeRef? switch SecItemCopyMatching(query as CFDictionary, &item) { case errSecSuccess: guard let data = item as? Data else { return nil } return SymmetricKey(data: data) case errSecItemNotFound: return nil case let status: throw KeyStoreError("Keychain read failed: \(status.message)") } }
I was also attempting to add the following attributes to the keychain query (but commented them out because I was attempting to troubleshoot this issue)
Code Block swift kSecAttrIsPermanent: true, kSecAttrCanEncrypt: true, kSecAttrCanDecrypt: true, kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, kSecUseDataProtectionKeychain: true, kSecAttrIsInvisible: true,
I've tried storing the key as both a a kSecClassGenericPassword and a kSecClassKey, and it returns the same -50 ("One or more parameters passed to a function were not valid.") error. I've tried storing the key as both Data and the SymmetricKey iteself, and I have tried storing the ApplicationTag as both a String and as Data. Neither of these resolve the issue. I'm hoping someone has some ideas on what I'm missing here.
I've been following the instructions listed here: https://developer.apple.com/documentation/cryptokit/storing_cryptokit_keys_in_the_keychain
Here is my code to convert to a rawRepresentation (the code supplied in the CryptoKit Keys in the Keychain article didn't compile unfortunately).
Code Block swift import Foundation import CryptoKit extension SymmetricKey: GenericPasswordConvertible { public var description: String { return "" } init<D>(rawRepresentation data: D) throws where D: ContiguousBytes { self.init(data: data) } var rawRepresentation: Data { var intArr = [UInt8]() self.withUnsafeBytes { ptr in intArr.append(contentsOf: ptr) } return Data(intArr) } }
Thanks in advance for the help.