I changed the bundle ID then it works...I doubt if it is because the previous bundle ID is too long.
Post
Replies
Boosts
Views
Activity
Thanks so much. I wrote the below two methods to create and read keys.
Another small question - is it possible to store/get the specific creation time of the key generated when reading the key from the keychain?
internal func generateAndStoreSymmetricKey(withKeychainTag: String) throws {
// Parameter:
let alias = withKeychainTag
let key = SymmetricKey(size: .bits256)
let addQuery:[CFString:Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrLabel: alias,
kSecAttrAccount: "Account \(alias)",
kSecAttrService: "Service \(alias)",
kSecReturnAttributes: true,
kSecValueData: key.rawRepresentation
]
var result: CFTypeRef?
let status = SecItemAdd(addQuery as CFDictionary, &result)
guard status == errSecSuccess else {
throw Error.client("Failed to insert symmetric key into keychain: \(withKeychainTag)")
}
}
internal func retrieveSymmetricKey(withKeychainTag: String) throws -> SymmetricKey? {
// Parameter:
let alias = withKeychainTag
// Seek a generic password with the given account.
let query = [kSecClass: kSecClassGenericPassword,
kSecAttrAccount: "Account \(alias)",
kSecUseDataProtectionKeychain: true,
kSecReturnData: true] as [String: Any]
// Find and cast the result as data.
var item: CFTypeRef?
switch SecItemCopyMatching(query as CFDictionary, &item) {
case errSecSuccess:
guard let data = item as? Data else { throw Error.client("Fail to convert the key reference to Data.") }
return try SymmetricKey(rawRepresentation: data) // Convert back to a key.
case errSecItemNotFound: return nil
default: throw Error("Error in reading the key")
}
}
Thanks for answering!
Based on our guideline, we are supposed to use AES-CBC for encryption.
And I generated a random 256-bits symmetric key to achieve this. (Please find the code snippets below.)
I have a question here - how can I store such a symmetric key into keychain? Thanks!
internal func generateSymmetricEncryptionKey() throws -> String {
var keyData = Data(count: 32)
let result = keyData.withUnsafeMutableBytes {
SecRandomCopyBytes(kSecRandomDefault, 32, $0.baseAddress!)
}
guard result == errSecSuccess else {
throw error
}
return keyData.base64EncodedString()
}