52

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

4

7 回答 7

84

为所有课程做这件事

目标-C:

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

迅速:

let secItemClasses = [kSecClassGenericPassword, kSecClassInternetPassword, kSecClassCertificate, kSecClassKey, kSecClassIdentity]
for itemClass in secItemClasses {
    let spec: NSDictionary = [kSecClass: itemClass]
    SecItemDelete(spec)
}
于 2012-12-29T22:02:21.350 回答
15

关于如何删除应用程序可访问的所有钥匙串项目的已接受答案的 Xamarin iOS 版本(MonoTouch)如下:

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

如果您想确保确实删除了记录,您可以在开发期间使用以下代码检查特定类型的 KeyChain 中的项目数:

SecStatusCode scc;
var records = SecKeyChain.QueryAsRecord(new SecRecord(SecKind.GenericPassword), 1000, out scc);
于 2014-08-14T05:40:01.437 回答
14

我用 Swift 重写了 Daij-Djan 的回答:

let secItemClasses = [kSecClassGenericPassword,
    kSecClassInternetPassword,
    kSecClassCertificate,
    kSecClassKey,
    kSecClassIdentity]
for secItemClass in secItemClasses {
    let dictionary = [kSecClass as String:secItemClass]
    SecItemDelete(dictionary as CFDictionary)
}
于 2015-11-07T04:43:32.573 回答
9

斯威夫特版本

import Foundation
import Security


public class Keychain: NSObject {
  public class func logout()  {
    let secItemClasses =  [
      kSecClassGenericPassword,
      kSecClassInternetPassword,
      kSecClassCertificate,
      kSecClassKey,
      kSecClassIdentity,
    ]
    for itemClass in secItemClasses {
      let spec: NSDictionary = [kSecClass: itemClass]
      SecItemDelete(spec)
    }
  }
}

用法:

Keychain.logout()
于 2018-12-31T01:14:37.403 回答
7

感谢 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);        
}
于 2012-12-29T22:02:14.437 回答
1

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

于 2012-12-29T21:35:59.003 回答
0

不幸的是,这个问题的所有答案似乎都已过时(自 iOS 7.0+ 起),因为它们不会删除kSecAttrSynchronizable设置了标志的钥匙串条目(允许通过 iCloud 同步到其他设备)。

要删除此类条目,可以在删除查询中添加一个条目,指定kSecAttrSynchronizable: kSecAttrSynchronizableAny

let secItemClasses = [kSecClassGenericPassword,
    kSecClassInternetPassword,
    kSecClassCertificate,
    kSecClassKey,
    kSecClassIdentity]
for secItemClass in secItemClasses {
    let query: NSDictionary = [
        kSecClass as String: secItemClass,
        kSecAttrSynchronizable as String: kSecAttrSynchronizableAny
    ]
    SecItemDelete(query)
}
于 2021-03-30T13:03:00.913 回答