LocalAuthentication.framework
is a high-level API that can be used to authenticate the user via Touch ID. The app can't access any data associated with the enrolled fingerprint and is notified only whether authentication was successful.Security.framework
is a lower level API to access keychain services. This is a secure option if your app needs to protect some secret data with biometric authentication, since the access control is managed on a system-level and can not easily be bypassed. Security.framework
has a C API, but there are several open source wrappers available, making access to the keychain as simple as to NSUserDefaults. Security.framework
underlies LocalAuthentication.framework
; Apple recommends to default to higher-level APIs whenever possible.LocalAuthentication.framework
or the Security.framework
, will be a control that can be bypassed by an attacker as it does only return a boolean and no data to proceed with. See Don't touch me that way, by David Lindner et al for more details.evaluatePolicy
of the LAContext
class.deviceOwnerAuthentication
(Swift) or LAPolicyDeviceOwnerAuthentication
(Objective-C): When available, the user is prompted to perform Touch ID authentication. If Touch ID is not activated, the device passcode is requested instead. If the device passcode is not enabled, policy evaluation fails.deviceOwnerAuthenticationWithBiometrics
(Swift) or LAPolicyDeviceOwnerAuthenticationWithBiometrics
(Objective-C): Authentication is restricted to biometrics where the user is prompted for Touch ID.evaluatePolicy
function returns a boolean value indicating whether the user has authenticated successfully.SecAccessControl
attribute, which will allow access to the item from the keychain only after the user has passed Touch ID authentication (or passcode, if such a fallback is allowed by attribute parameters).kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
parameter) and after Touch ID authentication for the currently enrolled fingers only (SecAccessControlCreateFlags.biometryCurrentSet
parameter):LocalAuthentication.framework
is used in an app, the output will contain both of the following lines (remember that LocalAuthentication.framework
uses Security.framework
under the hood):Security.framework
is used, only the second one will be shown.kSecAccessControlBiometryCurrentSet
(before iOS 11.3 kSecAccessControlTouchIDCurrentSet
). This will make sure that a user needs to authenticate with biometrics (e.g. Face ID or Touch ID) before accessing the data in the keychain item. Whenever the user adds a fingerprint or facial representation to the device, it will automatically invalidate the entry in the Keychain. This makes sure that the keychain item can only ever be unlocked by users that were enrolled when the item was added to the keychain.kSecAccessControlBiometryAny
(before iOS 11.3 kSecAccessControlTouchIDAny
). This will make sure that a user needs to authenticate with biometrics (e.g. Face ID or Touch ID) before accessing the data in the Keychain entry. The Keychain entry will survive any (re-)enroling of new fingerprints or facial representation. This can be very convenient if the user has a changing fingerprint. However, it also means that attackers, who are somehow able to enrole their fingerprints or facial representations to the device, can now access those entries as well.kSecAccessControlUserPresence
can be used as an alternative. This will allow the user to authenticate through a passcode if the biometric authentication no longer works. This is considered to be weaker than kSecAccessControlBiometryAny
since it is much easier to steal someone's passcode entry by means of shouldersurfing, than it is to bypass the Touch ID or Face ID service.kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
or the kSecAttrAccessibleWhenPasscodeSet
protection class is set when the SecAccessControlCreateWithFlags
method is called. Note that the ...ThisDeviceOnly
variant will make sure that the keychain item is not synchronized with other iOS devices.Note, a data protection class specifies the access methodology used to secure the data. Each class uses different policies to determine when the data is accessible.
evaluatePolicy
function so that it returns True
even if authentication was not successfully performed. Use the ios ui biometrics_bypass
command to bypass the insecure biometric authentication. Objection will register a job, which will replace the evaluatePolicy
result. It will work in both, Swift and Objective-C implementations.kSecAccessControlUserPresence
or similar is set), then once the device is unlocked, a key will be accessible.