I'm integrating TouchID into my app, for security reasons I need to block the user when he is trying to authenticate with newly added fingerprints [Which is added after enabling TouchID authentication in my app].
I can detect the biometry changes using LAContext's evaluatedPolicyDomainState. but this only says either biometric database was modified (fingers or faces were removed or added) or not.
Is there any other way I can find whether user has authenticated using newly added fingerprint
[added after enabling TouchID in my app] or not.
Any thoughts on this? appreciate any help and thanks in advance.
It is not possible to determine whether the biometric authentication took place with a "new" or "old" finger. This is a hardware limitation.
The biometric validation takes place in the Secure Enclave. The Secure Enclave simply returns a yes/no answer to the main processor. The main processor does not have any access to the actual biometric data that was validated.
You can, as you have noted, determine if the biometric database has been updated since you last evaluated the domain state. The best you can do is invalidate all biometric access if you determine that the database has been modified, even if that modification was the removal of a finger.
Related
I working on an app that is designed to be protected from unauthorized access (like, for instance, bank apps do). There are two protection options: by using biometrics (default one) and by user password. I wonder, what the best practices are to handle the situation when a user forget thier password.
I'm thinking to prompt user to enter device PIN in order to remind them the password, but I can't figure out how to do that.
I guess it really depends on exactly how sensible the information is and how you're currently storing/validating the password. But assuming your threat model is okay with a user being able to get access back just with the current device password, you could use the keychain API (not the friendliest of APIs) and store some kind of flag. When adding such item you would use SecAccessControlCreateFlag.devicePasscode which will always prompt the user for their iPhone passcode before accessing such entry. So say the user needs to reset it, if you're able to access the keychain entry, you know they entered the right device passcode and thus you should allow them to reset their app password. The main caveat would be that the user disabling their passcode or not having one would invalidate your flag so they would be locked out forever if they ever forget their app password. Of course there's a lot of additional nuance to the Keychain like whether the items get synced to other devices or not, when it's available, etc. but hopefully this is somewhat useful.
I'm trying to unlock data from the keychain / secure enclave via FaceID and make it accessible for the duration of the User session (without additional unlocks).
Per the documentation for kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly:
After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute do not migrate to a new device.
Yet, whenever I call SecItemCopyMatching() (documentation), I'm always prompted to perform a FaceID authorization.
Can someone explain what I might be doing wrong (or misunderstanding)?
The data protection class and the access control flags assigned to a keychain item are separate.
In your question you have detailed the data protection class that you have assigned, but the behaviour you are describing is resulting from the access control flags that were specified.
The data protection class refers to the lock state of the device, not the keychain item.
If you specify one or more of these values then the specified authentication (biometric and/or passcode) is required each time the keychain item is accessed.
If you only want the user to authenticate their presence the first time the item is accessed then you could specify no access control for the item and use the local authentication framework directly. Set a flag once the user has successfully authenticated and do not prompt them again in that session (or until a certain time hasn't elapsed or whatever logic you like).
OK. I suspect I just need to be directed to the appropriate "M" for "RTFM." I'm not new to iOS, but fairly new to keychain use. I am using a good keychain wrapper called "FXKeychain."
I have an app that includes a login, with a password stored in the default keychain.
I use TouchID to validate the user and fill in the password.
In order to do this, I display a "thumbprint" button, with an IBAction handler that runs the standard code:
self.s_authenticationContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Yo. Gimmie ur thumb.", reply: self.touchIDCallback)
The issue is, that once it is unlocked, subsequent touches of the button, using the above, skip the alert, and simply fall through.
This is an issue because the same button is displayed, even after the user is validated. I'd like to either:
Re-lock after entering the password, so the user must re-authenticate each time (preferred), or
Display a different button image that indicates the thumbprint is no longer necessary.
That means that I need to:
Find a way to re-lock the TouchID, or
Find out if the user is unlocked.
Any ideas?
Thanks!
It is your authentication context rather than the keychain that is 'unlocked'. If you allocate a new authentication context before calling evaluatePolicy then the touchID dialog will be shown again.
You can, however, actually use touchID to authenticate access to a keychain item directly. The Apple sample code demonstrates how to do this - https://developer.apple.com/library/ios/samplecode/KeychainTouchID/Introduction/Intro.html#//apple_ref/doc/uid/TP40014530-Intro-DontLinkElementID_2
So on iOS 8 we could check that current user IS device owner, because he have exactly the same fingerprint. iOS give us true or false value.
But how can we use this value as PIN-code for App's authorization? For example where could we store user's login and password, which we could read and then use in internet-service?
As stated in Apple documentation for Local Authentication(and as you mentioned):
Code:
- (void)evaluatePolicy:(LAPolicy)policy
localizedReason:(NSString *)localizedReason
reply:(void (^)(BOOL success,
NSError *error))reply
Reply block that is executed when policy evaluation finishes. This
block is evaluated on a private queue internal to the framework in an
unspecified threading context. You must not call
canEvaluatePolicy:error: in this block, because doing so could lead to
deadlock.
success: YES if policy evaluation succeeded, NO otherwise.
So there is not way to base your PIN, login/pass or auth-tocken on fingerprint. However you can encrypt it and store somewhere in the app's storage. So if fingerprint authentication succeeded you can use it to authorize access to the app and it's resources. Of course such tradeoff completely depend on your app's security restrictions.
What would be nice to have in Local Authentication API is ability to know that user updated(changed) fingerprints so you can request user to authenticate again. Unfortunately there is no such API.
We can also speculate if Apple may introduce hashes for fingerprint; but I think it may cause security threat if somebody steals the hash thus I do not believe we can see such API function.
I believe that in order to use the TOUCH ID for an application is not possible. All the other ios 3rd party applications have their own 3rd party fingerprint scanning software. the TouchID software on ios is unavailable for other apps, for "Security Reasons". And the Security Reasons are that TouchID saves all its fingerprint data in the A7, or A6 chip. and does not give out that information to 3rd party applications.
As we know OS X needs master password to unlock keychain and decrypt all data that is stored there. In general master password is stored in user's brains so there no any direct IT ways to compromise this password.
At the same time iOS makes some simplifications and it doesn't require master password that known only by user. So I became interested how is logic for iOS keychain unlocking and data decrypting implemented and found such explanation in Apple docs:
In iOS, an application always has access to its own keychain items and
does not have access to any other application’s items. The system
generates its own password for the keychain, and stores the key on the
device in such a way that it is not accessible to any application.
As I understand iOS generates master password by itself and stores it in some specific place.
My question is: does anybody know or have any ideas what is it place or way that used for storing master password that guarantees preventing from any IT attacks or third party accesses?
(I found some similar questions like this, but there are no any specific information.)
You can find a lot of information in the Apple iOS Security Whitepaper
Essentially the passcode is "tangled" with a device specific ID that is not available to executing code in order to generate keys. The keys used to unlock files and the keychain are kept in memory while the phone is unlocked (or after first unlock for some protection classes) but are discarded on lock or reboot (again depending on the protection classes) but the passcode itself is never stored in memory or a code accessible file system.