web-dev-qa-db-ja.com

iPhoneアプリのキーチェーンをリセットする

アプリのキーチェーンをリセットする方法があるかどうか知りたいのですが。私は何かが存在するかどうか疑問に思っています

[NSUserDefaults resetStandardUserDefaults]

キーホルダー用。アプリを削除してもキーチェーンはリセットされません。これまでのところ、私が知っている唯一の方法は、アプリからそれらを1つずつリセットすることです。

22
Jose Cherian

これまでのすべての回答は、削除する識別子を知っていることに依存しているため、次のソリューションを送信します既存のすべてのキーを削除しますアプリ用(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.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バージョン

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))")
}
58
Vegard
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"nameOfYourKeychain" accessGroup:nil];

[keychainItem resetKeychainItem];

はるかに簡単です:)

編集:以下の質問への回答-KeychainItemWrapperとは何ですか?

これはAppleからダウンロードできるクラスです: http://developer.Apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html

それをプロジェクトに追加してから、使用したい場所にインポートします。次に、上記で提供したコードスニペットを使用します。

11
jcrowson

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

ヘルパーメソッドを持たずにコードをドロップするだけの人のために。

2
mxcl