Search code examples
iphoneobjective-cioscocoa-touchios4

How do you reset an iPhone App's Keychain?


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.


Solution

  • 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))")
    }