How do you reset an iPhone App's Keychain?

22,289

Solution 1

As all of the answers so far rely on you knowing the identifiers you want to delete, I would like to submit the following solution that deletes ALL existing keys for the app (iOS only)

Objective-C:

-(void)resetKeychain {
    [self deleteAllKeysForSecClass:kSecClassGenericPassword];
    [self deleteAllKeysForSecClass:kSecClassInternetPassword];
    [self deleteAllKeysForSecClass:kSecClassCertificate];
    [self deleteAllKeysForSecClass:kSecClassKey];
    [self deleteAllKeysForSecClass:kSecClassIdentity];
}

-(void)deleteAllKeysForSecClass:(CFTypeRef)secClass {
    NSMutableDictionary* dict = [NSMutableDictionary dictionary];
    [dict setObject:(__bridge id)secClass forKey:(__bridge id)kSecClass];
    OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict);
    NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%ld)", result);
}

Swift 2.2:

func resetKeychain() {
    self.deleteAllKeysForSecClass(kSecClassGenericPassword)
    self.deleteAllKeysForSecClass(kSecClassInternetPassword)
    self.deleteAllKeysForSecClass(kSecClassCertificate)
    self.deleteAllKeysForSecClass(kSecClassKey)
    self.deleteAllKeysForSecClass(kSecClassIdentity)
}

func deleteAllKeysForSecClass(secClass: CFTypeRef) {
    let dict: [NSString : AnyObject] = [kSecClass : secClass]
    let result = SecItemDelete(dict)
    assert(result == noErr || result == errSecItemNotFound, "Error deleting keychain data (\(result))")
}

Swift 3:

func resetKeychain() {
    deleteAllKeysForSecClass(kSecClassGenericPassword)
    deleteAllKeysForSecClass(kSecClassInternetPassword)
    deleteAllKeysForSecClass(kSecClassCertificate)
    deleteAllKeysForSecClass(kSecClassKey)
    deleteAllKeysForSecClass(kSecClassIdentity)
}

func deleteAllKeysForSecClass(_ secClass: CFTypeRef) {
    let dict: [NSString : Any] = [kSecClass : secClass]
    let result = SecItemDelete(dict as CFDictionary)
    assert(result == noErr || result == errSecItemNotFound, "Error deleting keychain data (\(result))")
}

Solution 2

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"nameOfYourKeychain" accessGroup:nil];

[keychainItem resetKeychainItem];

Much simpler :)

Edit: In response to a question asked below - what is KeychainItemWrapper?

It's a class written by Apple that you can download here: http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html

Add it to your project and then import it where you would like to use it. Then use the code snippet I provided above.

Solution 3

Block-based version of Vegard’s solution:

void (^deleteAllKeysForSecClass)(CFTypeRef) = ^(CFTypeRef secClass) {
    id dict = @{(__bridge id)kSecClass: (__bridge id)secClass};
    OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict);
    NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%d)", (int)result);
};
deleteAllKeysForSecClass(kSecClassGenericPassword);
deleteAllKeysForSecClass(kSecClassInternetPassword);
deleteAllKeysForSecClass(kSecClassCertificate);
deleteAllKeysForSecClass(kSecClassKey);
deleteAllKeysForSecClass(kSecClassIdentity);

For those of us who like to just drop code in without having to have helper methods.

Share:
22,289
Jose Cherian
Author by

Jose Cherian

Updated on July 09, 2022

Comments

  • Jose Cherian
    Jose Cherian almost 2 years

    I would like to know if there is a way to reset my app's Keychain. I am wondering whether anything like [NSUserDefaults resetStandardUserDefaults] exists for keychain. Keychain is not reset even after the app is deleted. So far the only way I know is to reset them one by one from the app.