Googled but can't find anything on how to set this attribute for the keychain in swift. There's a few bits and pieces about it with Obj-C, but trying to find a correspondence between Swift usage of the keychain and Obj-C is bloddy impossible almost.
I've got some existing code (from the Realm Swift documentation) to set an encryption key, but want to set the access from the default to kSecAttrAccessibleAfterFirstUnlock.
class func getKey() -> NSData {
let keychainIdentifier = "Realm.EncryptionKey"
let keychainIdentifierData = keychainIdentifier.data(using: String.Encoding.utf8, allowLossyConversion: false)!
// First check in the keychain for an existing key
var query: [NSString: AnyObject] = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecReturnData: true as AnyObject
]
var dataTypeRef: AnyObject?
var status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }
if status == errSecSuccess {
return dataTypeRef as! NSData
}
// No pre-existing key from this application, so generate a new one
let keyData = NSMutableData(length: 64)!
let result = SecRandomCopyBytes(kSecRandomDefault, 64, keyData.mutableBytes.bindMemory(to: UInt8.self, capacity: 64))
assert(result == 0, "Failed to get random bytes")
// Store the key in the keychain
query = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecValueData: keyData
]
status = SecItemAdd(query as CFDictionary, nil)
return keyData
}
Add kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
to the query dictionary you use to add the key.
If you want to update the accessibility status after its already been added, you need to specify the kSecValueData
and kSecAttrAccessible
keys in the dictionary you pass to SecItemUpdate
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With