2011-08-22 8 views
21

私のアプリのキーチェーンをリセットする方法があるかどうかを知りたいと思います。私は何がiPhoneアプリのキーチェーンをリセットする

[NSUserDefaults resetStandardUserDefaults]

などのキーチェーンのために存在するかどうかを疑問に思って。アプリを削除してもキーチェーンはリセットされません。これまで私が知っている唯一の方法は、アプリから1つ1つずつリセットすることです。

+0

@ serge-kこの疑問は2012年に2011年に尋ねられました。 –

+0

他の答えはここにあります。http://stackoverflow.com/questions/14086085/how-to-delete-all -keychain-items-accessible-to-an-appは、より最新のソリューションです。私はちょうどリンクとしてそれを残すことができます、私は重複フラグを削除しました。 –

答えて

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 Simulator - > Reset Content and Settings' – 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

ありがとうございます。また、最もシンプルで表現力豊かな実装です。 –

関連する問題