ios 重置 iPhone 应用程序的钥匙串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7142774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:12:29  来源:igfitidea点击:

Reset An iPhone App's Keychain

iphoneobjective-cioscocoa-touchios4

提问by Jose Cherian

I would like to know if there is a way to reset My app's keychain. I am wondering whether anything exist like

我想知道是否有办法重置我的应用程序的钥匙串。我想知道是否存在类似的东西

[NSUserDefaults resetStandardUserDefaults]

[NSUserDefaults resetStandardUserDefaults]

for keychain. Key chain 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.

用于钥匙扣。即使删除应用程序后,钥匙链也不会重置。到目前为止,我知道的唯一方法是从应用程序中一一重置它们。

回答by Vegard

As all of the answers so far relies on that you know the identifiers you want to delete I would like to submit the following solution that deletes ALL existing keysfor the app (iOS only)

由于到目前为止所有答案都依赖于您知道要删除的标识符,因此我想提交以下解决方案,删除应用程序的所有现有密钥(仅限 iOS)

-(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.2version:

斯威夫特 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 3version

斯威夫特 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))")
}

回答by jcrowson

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

[keychainItem resetKeychainItem];

Much simpler :)

简单得多:)

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

编辑:回应下面提出的一个问题 - 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

这是 Apple 编写的类,您可以在这里下载: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.

将其添加到您的项目中,然后将其导入到您想要使用的位置。然后使用我上面提供的代码片段。

回答by mxcl

Block-based version of @Vegard's solution:

@Vegard 解决方案的基于块的版本:

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.

对于我们这些喜欢直接插入代码而不必使用辅助方法的人。

回答by JimP

- (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];


}