鑰匙串訪問控制(帶密碼後備的 TouchID)
Keychain 允許使用特殊的 SecAccessControl 屬性儲存專案,這樣只有在使用者使用 Touch ID 進行身份驗證後才能從 Keychain 獲取專案(如果允許這樣的回退,則允許使用密碼)。僅通知應用程式驗證是否成功,整個 UI 由 iOS 管理。
首先,應建立 SecAccessControl 物件:
迅速
let error: Unmanaged<CFError>?
guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .userPresence, &error) else {
fatalError("Something went wrong")
}
接下來,使用 kSecAttrAccessControl 鍵將其新增到字典中(與其他示例中使用的 kSecAttrAccessible 鍵互斥):
迅速
var dictionary = [String : Any]()
dictionary[kSecClass as String] = kSecClassGenericPassword
dictionary[kSecAttrLabel as String] = "com.me.myapp.myaccountpassword" as CFString
dictionary[kSecAttrAccount as String] = "My Name" as CFString
dictionary[kSecValueData as String] = "new_password!!".data(using: .utf8) as! CFData
dictionary[kSecAttrAccessControl as String] = accessControl
並像以前一樣儲存它:
迅速
let lastResultCode = SecItemAdd(query as CFDictionary, nil)
要訪問儲存的資料,只需查詢 Keychain 以獲取金鑰。Keychain Services 將向使用者顯示身份驗證對話方塊並返回資料或 nil,具體取決於是否提供了合適的指紋或匹配的密碼。
(可選)可以指定提示字串:
迅速
var query = [String: Any]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecReturnData as String] = kCFBooleanTrue
query[kSecAttrAccount as String] = "My Name" as CFString
query[kSecAttrLabel as String] = "com.me.myapp.myaccountpassword" as CFString
query[kSecUseOperationPrompt as String] = "Please put your fingers on that button" as CFString
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
如果使用者拒絕,取消或未通過授權,請注意 status
將成為 err
。
迅速
if status == noErr {
let password = String(data: queryResult as! Data, encoding: .utf8)!
print("Password: \(password)")
} else {
print("Authorization not passed")
}