2011-08-22 34 views
21

Tôi muốn biết nếu có cách nào để đặt lại khóa của ứng dụng của tôi. Tôi đang phân vân không biết bất cứ điều gì tồn tại nhưĐặt lại Keychain của iPhone App

[NSUserDefaults resetStandardUserDefaults]

cho keychain. Chuỗi khóa không được đặt lại ngay cả sau khi ứng dụng bị xóa. Cho đến nay, cách duy nhất tôi biết là đặt lại từng cái một từ ứng dụng.

+0

@ serge-k, câu hỏi đó đã được hỏi vào năm 2012 trong khi điều này là vào năm 2011. –

+0

Đúng, chỉ cần tìm câu trả lời khác được tìm thấy ở đây http://stackoverflow.com/questions/14086085/how-to-delete-all -keychain-items-accessible-to-an-app là một giải pháp cập nhật hơn. Tôi chỉ có thể để nó như một liên kết, tôi đã xóa cờ trùng lặp. –

Trả lời

52

Như tất cả các câu trả lời cho đến nay dựa vào đó bạn biết được định danh bạn muốn xóa tôi muốn gửi giải pháp sau đó xóa TẤT CẢ phím hiện cho ứng dụng (iOS chỉ)

-(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 phiên bản:

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 phiên bản 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

có cách nào để xóa tất cả các móc khóa theo cách thủ công bằng chính điện thoại không? một cái gì đó giống như các hướng dẫn [ở đây] (http://www.imore.com/how-access-and-view-your-icloud-keychain-passwords-ios-7) – abbood

+2

@abbood lập trình mà nên là không thể. Tại sao? Vì ứng dụng của bạn là hộp cát và bạn sẽ không bao giờ có thể xóa tất cả các mặt hàng keychain ** khỏi các ứng dụng khác **. Chỉ có tôi * đoán * kịch bản có thể là sử dụng trình mô phỏng chính nó 'iOS Simulator -> Đặt lại nội dung và cài đặt ' – 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

Bạn có thể thêm một số nhận xét để giúp người dùng hiểu mã của bạn đang làm gì không –

+0

@JimP, bạn có thể giải thích một chút không. bạn vẫn cần cung cấp tất cả các phím để đặt lại đúng không? Tôi có rất nhiều thông tin an toàn và tôi muốn đặt lại tất cả chúng có nhu cầu. –

+4

Thật là một câu trả lời tệ hại ... – Chris

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

[keychainItem resetKeychainItem]; 

đơn giản hơn nhiều :)

Edit: Để đối phó với một câu hỏi hỏi dưới đây - KeychainItemWrapper là gì?

Đó là một lớp được viết bởi Apple mà bạn có thể tải về tại đây: http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Listings/Classes_KeychainItemWrapper_m.html

Thêm nó vào dự án của bạn và sau đó import nó nơi bạn muốn sử dụng nó. Sau đó sử dụng đoạn mã tôi đã cung cấp ở trên.

+2

Xin chào, KeychainItemWrapper là gì? – hzxu

+0

@hzxu đã cập nhật câu trả lời, cảm ơn. – jcrowson

+1

Cảm ơn, nhưng nếu tôi cần phải có một vài cặp khóa-giá trị và tôi không thể sử dụng từ điển cho tất cả nội dung của mình và lưu nó vào khóa chuẩn như 'kSecValueData' vì giá trị cần phải là chuỗi, thì tôi cần tạo nhiều 'KeychainItemWrapper' là số cặp khóa-giá trị của tôi? – hzxu

2

phiên bản Block-dựa của @ giải pháp Vegard của:

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

Đối với những người trong chúng ta ai muốn chỉ cần thả mã trong mà không cần phải có phương pháp helper.

+0

Cảm ơn vì điều này. Đó cũng là cách triển khai đơn giản và dễ hiểu nhất. –

Các vấn đề liên quan