Я создаю Keypair с привязкой ACL, и я использовал ключ kSecAccessControlUserPresence
, чтобы предположить, что он сначала запустит TouchID / FaceID, а если не зарегистрируется, то запросит пароль и его нормально работает на iPhone6Plus, но на моем iPhoneX запрос пароля даже язарегистрировал мое лицо на FaceID.Итак, у меня есть следующие вопросы.
kSecAccessControlUserPresence
говорит, что сначала он запросит по биометрике (TouchId / FaceId), и если он не зарегистрирован, а затем запросит пароль, верно ли это понимание? - Если мое понимание выше неверно, то как я могу сначала выбрать биометрическую метрику, а затем нажать на пароль?
Вот мой код.
private func generateHardwareKeyPairEC(keypairAttributes : KeyPairAttributes, completionHandler: @escaping (OSStatus?) -> Void ) {
// Access Control List
let accessControl: SecAccessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, [SecAccessControlCreateFlags.privateKeyUsage, SecAccessControlCreateFlags.userPresence], nil)!
// Public Key parameters
let publicKeyParams: [String: Any] = [
kSecAttrLabel as String: keypairAttributes.keyLabel!,
kSecAttrApplicationTag as String : keypairAttributes.keyApplicationTag!
]
// Private Key parameters
let privateKeyParams: [String: Any] = [
kSecAttrLabel as String: keypairAttributes.keyLabel!,
kSecAttrApplicationTag as String : keypairAttributes.keyApplicationTag!,
kSecAttrIsPermanent as String: true,
kSecAttrAccessControl as String: accessControl,
]
//Key Pair parameters
let params: [String: Any] = [
kSecAttrKeyType as String: kSecAttrKeyTypeEC,//key type will be used here
kSecAttrKeySizeInBits as String: keypairAttributes.keySize!,
kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
kSecPublicKeyAttrs as String : publicKeyParams,
kSecPrivateKeyAttrs as String: privateKeyParams
]
//var publicKey, privateKey: SecKey?
DispatchQueue.global(qos: .default).async { // 1
let status = SecKeyGeneratePair(params as CFDictionary, &self.publicKey, &self.privateKey)
if status == noErr {
print("Private key: \(String(describing: self.privateKey))\nPublic key: \(String(describing: self.publicKey))")
print("Private key: \(String(describing: self.privateKey))\nPublic key: \(String(describing: self.publicKey))")
completionHandler(status)
} else {
print("Failed to generate key pairs")
completionHandler(status)
}
}
}