ios 如何删除应用程序可访问的所有钥匙串项目?

wvt8vs2t  于 2023-01-18  发布在  iOS
关注(0)|答案(8)|浏览(166)

我需要删除iOS上的零散钥匙链项目(可能是旧版本的应用程序编写的)。有简单的方法可以实现这一点吗?

2guxujil

2guxujil1#

为所有类执行此操作

目标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)
}
yquaqz18

yquaqz182#

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

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

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

nimxete23#

我在《斯威夫特》中改写了戴杰-詹的回答:

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

yvt65v4c4#

快速版本

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()
bcs8qyzn

bcs8qyzn5#

感谢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);        
}
relj7zay

relj7zay6#

不幸的是,这个问题的所有答案似乎都过时了(自iOS 7.0+以来),因为它们不会删除设置了kSecAttrSynchronizable标志的钥匙串条目(允许通过iCloud同步到其他设备)。
要删除这样的条目,crucible需要向删除查询添加一个条目,指定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)
}
unftdfkk

unftdfkk7#

你可以看看实用程序文件夹中的钥匙链访问应用程序。如果你启动应用程序并点击“所有项目”,它应该会显示你用这台特定计算机创建的所有项目。开发人员的通常以com开头。

tuwxkamq

tuwxkamq8#

当你使用Mac作为目标进行单元测试时,使用kSecClassCertificate清除所有证书时要小心,因为这会清除你的开发证书。你可以简单地撤销现有的证书,但在CI/CD管道中这是行不通的。

相关问题