KeychainAccess icon indicating copy to clipboard operation
KeychainAccess copied to clipboard

TouchID only when reading an item, not writing

Open jkritikos opened this issue 7 years ago • 8 comments

I'm trying to implement the simplest of scenarios: Write to the keychain, without requiring the user to authenticate (touchID) Use touch ID when reading this item from the keychain. I've tried various combinations of the accessibility and authentication policy but I end up with either:

  1. Reading and writing WITHOUT touch ID authentication
  2. Reading and writing WITH touch ID authentication

Is it possible to do what I'm trying? If so, can you please provide an example of how to write the item to the keychain, and only request touch ID authentication when reading it?

Thanks for your help!

jkritikos avatar Oct 05 '17 13:10 jkritikos

@jkritikos The problem is that set does a SecItemCopyMatching first, to determine if the item is already in the Keychain. To do this, it needs the authentication. I changed it to do a SecItemAdd first and if that returns a errSecDuplicateItem try to update it via SecItemUpdate for my purposes.

@kishikawakatsumi Is there a reason why SecItemCopyMatching is used or could it be changed to the method described above?

moogle19 avatar Dec 07 '17 07:12 moogle19

I have no plan to change current behavior for backward compatibility.

kishikawakatsumi avatar Dec 07 '17 08:12 kishikawakatsumi

@kishikawakatsumi Could we introduce a new method e.g add which doesn't call SecItemCopyMatching before adding to avoid the TouchID dialog when adding an item?

moogle19 avatar Dec 07 '17 09:12 moogle19

@moogle19

Could we introduce a new method e.g add which doesn't call SecItemCopyMatching before adding to avoid the TouchID dialog when adding an item?

There is worth considering, thanks.

kishikawakatsumi avatar Dec 11 '17 06:12 kishikawakatsumi

Has the behaviour for set described above changed since this issue was opened? Because, I have the opposite problem: I do want the Touch/Face ID prompt when saving, but it is not showed. The save goes through without it. Thanks.

KemalPajevic avatar Jan 22 '19 07:01 KemalPajevic

@KemalPajevic You can try this

import LocalAuthentication

    func showBiometricsAuthentication() {
        let context = LAContext()
        var error: NSError?
        let policy: LAPolicy = .deviceOwnerAuthenticationWithBiometrics
        
        if context.canEvaluatePolicy(policy, error: &error) {
            context.evaluatePolicy(policy, localizedReason: "🤪") { (success, err) in
                
            }
        } else {
            // could not evaluate
        }
    }

wolfcon avatar Aug 02 '19 02:08 wolfcon

@moogle19 Using SecItemUpdate also seems that requires authentication so even using it then the UI still shows. Do you have an example how not to show auth UI on SecItemUpdate but to show when reading the keychain?

plamenterziev avatar Sep 16 '19 20:09 plamenterziev

It's possible to verify whether the item is present or absent without actually reading the item's contents (and therefore, authenticating). Then, the item can be written to by first removing the old one and then writing it.

richardtop avatar May 10 '22 22:05 richardtop