How do you reset an iPhone App's Keychain?

前端 未结 4 1651
清酒与你
清酒与你 2020-12-13 06:44

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 k

相关标签:
4条回答
  • 2020-12-13 07:31

    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.

    0 讨论(0)
  • 2020-12-13 07:36
    - (void)resetKeychainItem
    {
        OSStatus junk = noErr;
        if (!keychainItemData) {
            self.keychainItemData = [[NSMutableDictionary alloc] init];
        } else if (keychainItemData){
            NSMutableDictionary *tempDictionary = [self dictionaryToSecItemFormat:keychainItemData];
            junk = SecItemDelete((CFDictionaryRef)tempDictionary);
            if ( junk != noErr ) {
                UIAlertView *dialog = [[UIAlertView alloc] initWithTitle:@"Keychain Error" message:[NSString stringWithFormat:@"A problem with updating the secure Keychain items with this information (likely, this email address information is duplicated in another Player).  Error code: %d %@", junk, [self resultText:-junk]] delegate:self cancelButtonTitle:NSLocalizedStringFromTable(@"Ok", @"Localizable", @"display text") otherButtonTitles:nil];
                [dialog show];
                [dialog release];
                //NSAssert( junk == noErr || junk == errSecItemNotFound, @"Problem deleting current dictionary." );
                return;
            }
        }
    
        // Default attributes for keychain item.
        [keychainItemData setObject:@"" forKey:(id)kSecAttrAccount];
        [keychainItemData setObject:@"" forKey:(id)kSecValueData];
        [keychainItemData setObject:@"" forKey:(id)kSecAttrLabel];
        [keychainItemData setObject:@"" forKey:(id)kSecAttrDescription];
        [keychainItemData setObject:@"" forKey:(id)kSecAttrComment];
        // Default data for keychain item.
        [keychainItemData setObject:@"" forKey:(id)kSecAttrModificationDate];
        [keychainItemData setObject:@"" forKey:(id)kSecAttrService];
    
    
    }
    
    0 讨论(0)
  • 2020-12-13 07:40
    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.

    0 讨论(0)
  • 2020-12-13 07:47

    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))")
    }
    
    0 讨论(0)
提交回复
热议问题