2012-12-29 32 views
31

我有我需要删除的iOS上丢失钥匙串项目(可能由旧版本的应用程序编写)。有没有简单的方法来实现这一目标?如何删除应用程序可访问的所有钥匙串项目?

+1

看到http://stackoverflow.com/questions/10966969/enumerate-all-keychain-items-in-my-ios-application为让您可以访问所有的项目,然后删除每一个.. –

回答

62

做的所有类

NSArray *secItemClasses = @[(__bridge id)kSecClassGenericPassword, 
         (__bridge id)kSecClassInternetPassword, 
         (__bridge id)kSecClassCertificate, 
         (__bridge id)kSecClassKey, 
         (__bridge id)kSecClassIdentity]; 
for (id secItemClass in secItemClasses) { 
    NSDictionary *spec = @{(__bridge id)kSecClass: secItemClass}; 
    SecItemDelete((__bridge CFDictionaryRef)spec); 
} 
+1

非常感谢!公认。 – sqreept

+0

我使用一个字面值为NSDictionary,所以它的xcode4.5 +,但如果某人需要更老的gcc/llvm支持使用dictionaryWithObject:forKey: –

+4

这不是一个字典文字,它应该是'NSDictionary * spec = @ {(__ bridge id)kSecClass: secItemClass};' – kevboh

1

您可以查看Utilities文件夹中的KeyChain Access应用程序。如果启动该应用程序并单击“所有项目”,它应显示您使用此特定计算机创建的所有项目。开发人员通常以com开头。

+0

对于Mac,您的答案是完美的,但在iOS上,Keychain Access应用程序不存在。不管怎么说,还是要谢谢你! – sqreept

6

由于Daij-Djan我得到这个解决方案:

for (id secclass in @[ 
    (__bridge id)kSecClassGenericPassword, 
    (__bridge id)kSecClassInternetPassword, 
    (__bridge id)kSecClassCertificate, 
    (__bridge id)kSecClassKey, 
    (__bridge id)kSecClassIdentity]) { 
    NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
            secclass, (__bridge id)kSecClass, 
            nil]; 

    SecItemDelete((__bridge CFDictionaryRef)query);   
} 
+0

现在我得到了同样的结果:嘿嘿 –

+0

很高兴看到,一旦OP与您合作的答案:) –

+1

我需要的答案。我必须做的工作...对吗? – sqreept

9

Xamarin的iOS版本(MonoTouch的)的accepted answer如何删除所有钥匙串项可访问的应用程序低于:

foreach (var recordKind in new []{ 
       SecKind.GenericPassword, 
       SecKind.Certificate, 
       SecKind.Identity, 
       SecKind.InternetPassword, 
       SecKind.Key, 
      }) 
    { 
      SecRecord query = new SecRecord(recordKind); 
      SecKeyChain.Remove(query); 
    } 

如果你想确保你确实删除记录,你可能期间之前特定种类的钥匙串项目的发展支票号码后,此代码:

SecStatusCode scc; 
var records = SecKeyChain.QueryAsRecord(new SecRecord(SecKind.GenericPassword), 1000, out scc); 
+1

非常感谢! –

8

我在斯威夫特改写Daij-Djan的答案:

let secItemClasses = [kSecClassGenericPassword, 
    kSecClassInternetPassword, 
    kSecClassCertificate, 
    kSecClassKey, 
    kSecClassIdentity] 
for secItemClass in secItemClasses { 
    let dictionary = [kSecClass as String:secItemClass] 
    SecItemDelete(dictionary) 
} 
+0

此代码导致我崩溃。问题发生在hashValue变量(至少在32位平台上)中进行CFHash到Int转换。 CFHash返回一个UINT,它在swift中转换为Int时可能会溢出。我建议将该行更改为'public var hashValue:Int {return Int(bitPattern:CFHash(self))}'以确保它不会溢出。 – Brett

+1

CFString免费桥接到NSString,桥接到swift字符串,所以你可以施放它们,即'let dictionary = [kSecClass as String:secItemClass as String]' – Brandon

+3

Swift 3编译器会抱怨,除非你写:“SecItemDelete(dictionary作为CFDictionary)“ – Laurent

相关问题