How to delete all keychain items accessible to an app?

Objective CIos

Objective C Problem Overview


I have stray keychain items on iOS (probably written by old version of app) that I need to delete. Is there an easy way to achieve this?

Objective C Solutions


Solution 1 - Objective C

Do it for all classes

Objective-C:

NSArray *secItemClasses = @[(__bridge id)kSecClassGenericPassword, (__bridge id)kSecClassInternetPassword, (__bridge id)kSecClassCertificate, (__bridge id)kSecClassKey, (__bridge id)kSecClassIdentity]; for (id secItemClass in secItemClasses) { NSDictionary *spec = @{(__bridge id)kSecClass: secItemClass}; SecItemDelete((__bridge CFDictionaryRef)spec); }

Swift:

let secItemClasses = [kSecClassGenericPassword, kSecClassInternetPassword, kSecClassCertificate, kSecClassKey, kSecClassIdentity] for itemClass in secItemClasses { let spec: NSDictionary = [kSecClass: itemClass] SecItemDelete(spec) }

Solution 2 - Objective C

Xamarin iOS version (MonoTouch) of accepted answer on How to delete all keychain items accessible to an app is below:

foreach (var recordKind in new []{
                SecKind.GenericPassword,
                SecKind.Certificate,
                SecKind.Identity,
                SecKind.InternetPassword,
                SecKind.Key,
            })
    {
          SecRecord query = new SecRecord(recordKind);
          SecKeyChain.Remove(query);
    }

If you want to make sure you indeed delete the records, you may during development check number of items in KeyChain of specific kind before and after with this code:

SecStatusCode scc;
var records = SecKeyChain.QueryAsRecord(new SecRecord(SecKind.GenericPassword), 1000, out scc);

Solution 3 - Objective C

I rewrote Daij-Djan's answer in Swift:

let secItemClasses = [kSecClassGenericPassword,
	kSecClassInternetPassword,
	kSecClassCertificate,
	kSecClassKey,
	kSecClassIdentity]
for secItemClass in secItemClasses {
	let dictionary = [kSecClass as String:secItemClass]
	SecItemDelete(dictionary as CFDictionary)
}

Solution 4 - Objective C

Swift version

import Foundation
import Security


public class Keychain: NSObject {
  public class func logout()  {
    let secItemClasses =  [
      kSecClassGenericPassword,
      kSecClassInternetPassword,
      kSecClassCertificate,
      kSecClassKey,
      kSecClassIdentity,
    ]
    for itemClass in secItemClasses {
      let spec: NSDictionary = [kSecClass: itemClass]
      SecItemDelete(spec)
    }
  }
}

usage:

Keychain.logout()

Solution 5 - Objective C

Thanks to Daij-Djan I got to this solution:

for (id secclass in @[
     (__bridge id)kSecClassGenericPassword,
     (__bridge id)kSecClassInternetPassword,
     (__bridge id)kSecClassCertificate,
     (__bridge id)kSecClassKey,
     (__bridge id)kSecClassIdentity]) {
    NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:                                  secclass, (__bridge id)kSecClass,                                  nil];
    
    SecItemDelete((__bridge CFDictionaryRef)query);        
}

Solution 6 - Objective C

You could take a look at the KeyChain Access application found in the Utilities folder. If you launch the application and click on "All Items," it should display all the items you have created with this specific computer. The developer ones usually start with com.

Solution 7 - Objective C

Unfortunately all answers of this question seem to be outdated (since iOS 7.0+) as they do not delete keychain entries that have the kSecAttrSynchronizable flag set (allow synchronization to other devices through iCloud).

To delete such entries it is crucible to add an entry to the delete query specifying kSecAttrSynchronizable: kSecAttrSynchronizableAny:

let secItemClasses = [kSecClassGenericPassword,
    kSecClassInternetPassword,
    kSecClassCertificate,
    kSecClassKey,
    kSecClassIdentity]
for secItemClass in secItemClasses {
    let query: NSDictionary = [
        kSecClass as String: secItemClass,
        kSecAttrSynchronizable as String: kSecAttrSynchronizableAny
    ]
    SecItemDelete(query)
}

Solution 8 - Objective C

Be cautious on using kSecClassCertificate to clear out all when you're unit testing using a Mac as a target as this will clear your development certificate. You can simply revoke the existing but in a CI/CD pipeline this won't work.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsqreeptView Question on Stackoverflow
Solution 1 - Objective CDaij-DjanView Answer on Stackoverflow
Solution 2 - Objective CAlex SorokoletovView Answer on Stackoverflow
Solution 3 - Objective CJim RhoadesView Answer on Stackoverflow
Solution 4 - Objective CScottyBladesView Answer on Stackoverflow
Solution 5 - Objective CsqreeptView Answer on Stackoverflow
Solution 6 - Objective CAgnosticDevView Answer on Stackoverflow
Solution 7 - Objective CJMaxView Answer on Stackoverflow
Solution 8 - Objective Cuser72982708View Answer on Stackoverflow