New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check if item exists in keychain without Touch ID auth #159
Comments
@kylejm I've tried a various way of that, there is no way to check whether the value exists or not, I think 😢 . If there is a possibility that the value would be protected with Touch ID, you should always execute keychain method asynchronously. |
Ah that's lame. No worries, I've worked around the problem by storing a flag to mark that the credential is stored. I hate this solution! 😩. Thanks for the reply :) |
@kishikawakatsumi would something like this be acceptable? Keeping in mind the below code is just a generic keychain query for example purposes, also the code below is specific to something we know is locked behind TouchID in the keychain. We currently use this to solve that problem. I'd def like to be using this as part of the framework. public func contains(_ key: String) -> Bool {
// We spcify kSecUseAuthenticationUIFail so that the error
// errSecInteractionNotAllowed will be returned if an item needs
// to authenticate with UI and the authentication UI will not be presented.
let keychainQuery: [AnyHashable: Any] = [
kSecClass as AnyHashable: kSecClassGenericPassword,
kSecAttrService as AnyHashable: Bundle.main.bundleIdentifier!,
kSecAttrAccount as AnyHashable: key,
kSecUseAuthenticationUI as AnyHashable: kSecUseAuthenticationUIFail
]
var result: AnyObject?
let status = SecItemCopyMatching(keychainQuery as CFDictionary, &result)
// If that status is errSecInteractionNotAllowed, then
// we know that the key is present, but you cannot interact with
// it without authentication. Otherwise, we assume the key is not present.
return status == errSecInteractionNotAllowed
} Maybe something like this in public func contains(_ key: String) throws -> Bool {
var query = options.query()
query[AttributeAccount] = key
query[UseAuthenticationUI] = UseAuthenticationUIFail
let status = SecItemCopyMatching(query as CFDictionary, nil)
switch status {
case errSecSuccess, errSecInteractionNotAllowed:
return true
case errSecItemNotFound:
return false
default:
throw securityError(status: status)
}
} |
@ChristopherCarranza Great thinking! This was an amazing workaround! |
Noting that UseAuthenticationUIFail is deprecated as of iOS 14. I'm using something like the following...
|
@hmlongco
Will this behavior persist if I change query to LAContext-based query with |
The code from @ChristopherCarranza above works, but you should also check for private func checkForKeychainItemExistence(itemName: String, completion: @escaping (Bool) -> Void) {
let keychainQuery: [AnyHashable: Any] = [
kSecClass as AnyHashable: kSecClassGenericPassword,
kSecAttrService as AnyHashable: "KEYCHAIN_SERVICE_NAME_HERE",
kSecAttrAccount as AnyHashable: itemName,
kSecUseAuthenticationUI as AnyHashable: kSecUseAuthenticationUIFail
]
var result: AnyObject?
let status = SecItemCopyMatching(keychainQuery as CFDictionary, &result)
// also check for errSecSuccess here!
completion(status == errSecInteractionNotAllowed || status == errSecSuccess)
} |
After playing around with it a lot I noticed some inconsistent behaviour of the Sometimes, it returns |
KEYCHAIN_SERVICE_NAME_HERE what that ?, I can't find service name |
Is this possible? Is it possible to see if a value exists at a given key in a keychain secured with Touch ID without prompting the user for their finger print?
If not, is there a way to check if the keychain, as a whole, exists without prompting for authentication?
I was torn as to whether I should ask this on here or on StackOverflow. I hope you don't mind me asking here? 😇 😅. I figured since I'm using your framework and couldn't find anything about my question in the README, I'd be coming back to you with any answer I got on SO to see how I do it via KeychainAccess.
Many thanks!
The text was updated successfully, but these errors were encountered: