2011-08-22 88 views
21

我想知道是否有方法来重置我的应用程序的钥匙串。我想知道是否任何存在一样重置iPhone应用程序的钥匙串

[NSUserDefaults resetStandardUserDefaults]

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

+0

@ serge-k,在2012年问这个问题,而这一个是在2011年。 –

+0

真的,只是想通过这里找到其他答案http://stackoverflow.com/questions/14086085/how-to-delete-all钥匙链项目可访问的应用程序是一个更新的解决方案。我可以把它作为一个链接,我删除了重复的标志。 –

回答

52

由于所有的答案迄今依赖于你知道标识符要删除我想提交下列解决方案删除所有现有密钥的应用程序(仅适用于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); 
} 

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

夫特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))") 
} 
+4

有没有办法使用手机本身手动删除所有钥匙链?像这样的说明[这里](http://www.imore.com/how-access-and-view-your-icloud-keychain-passwords-ios-7) – abbood

+2

@abbood以编程方式应该是不可能的。为什么?因为你的应用程序是沙盒,你永远无法从其他应用程序**删除所有钥匙串项目**。唯一的我*猜测*可能的情况是使用模拟器本身'iOS模拟器 - >重置内容和设置' – Honey

-5
- (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

@JimP,你可以给一点解释。你仍然需要提供所有的重置键吗?我有很多安全信息,我想重置所有这些信息。 –

+4

什么是糟糕的答案... – Chris

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

[keychainItem resetKeychainItem]; 

简单多了:)

编辑:在回答下面的问题问 - 什么是KeychainItemWrapper?

这是苹果编写,你可以在这里下载类:http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html

将它添加到您的项目,然后导入它,你想用它。然后使用我上面提供的代码片段。

+2

嗨,什么是KeychainItemWrapper? – hzxu

+0

@hzxu更新了答案,谢谢。 – jcrowson

+1

谢谢,但如果我需要有几个键值对,并且我不能使用字典来处理所有的东西,并将其存储为标准键(如“kSecValueData”),因为该值需要是字符串,那么我需要创建许多'KeychainItemWrapper'作为我的键值对的数量? – hzxu

2

基于块的@维加德的解决方案版本:

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); 

对于我们这些谁喜欢在刚落代码,而不必具有辅助方法。

+0

感谢你。这也是最简单和最具表现力的实现。 –