2011-08-22 48 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

感謝你。這也是最簡單和最具表現力的實現。 –

相關問題