LocalAuthentication.frameworkis 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.frameworkis 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.frameworkhas a C API, but there are several open source wrappers available, making access to the keychain as simple as to NSUserDefaults.
LocalAuthentication.framework; Apple recommends to default to higher-level APIs whenever possible.
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.
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.
LAPolicyDeviceOwnerAuthenticationWithBiometrics(Objective-C): Authentication is restricted to biometrics where the user is prompted for Touch ID.
evaluatePolicyfunction returns a boolean value indicating whether the user has authenticated successfully.
SecAccessControlattribute, 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).
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnlyparameter) and after Touch ID authentication for the currently enrolled fingers only (
LocalAuthentication.frameworkis used in an app, the output will contain both of the following lines (remember that
Security.frameworkunder the hood):
Security.frameworkis 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.
kSecAccessControlUserPresencecan 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
kSecAccessControlBiometryAnysince 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.
kSecAttrAccessibleWhenPasscodeSetprotection class is set when the
SecAccessControlCreateWithFlagsmethod is called. Note that the
...ThisDeviceOnlyvariant 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.
evaluatePolicyfunction so that it returns
Trueeven if authentication was not successfully performed. Use the
ios ui biometrics_bypasscommand to bypass the insecure biometric authentication. Objection will register a job, which will replace the
evaluatePolicyresult. It will work in both, Swift and Objective-C implementations.
kSecAccessControlUserPresenceor similar is set), then once the device is unlocked, a key will be accessible.