Как удалить все элементы цепочки для ключей, доступные для приложения?
У меня есть случайные элементы цепочки для ключей на iOS (вероятно, написанные старой версией приложения), которые мне нужно удалить. Есть ли простой способ добиться этого?
8 ответов
Сделать это для всех классов
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);
}
Версия 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);
Я переписал ответ Дайя-Джана в Swift:
let secItemClasses = [kSecClassGenericPassword,
kSecClassInternetPassword,
kSecClassCertificate,
kSecClassKey,
kSecClassIdentity]
for secItemClass in secItemClasses {
let dictionary = [kSecClass as String:secItemClass]
SecItemDelete(dictionary as CFDictionary)
}
Swift версия
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()
Благодаря 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);
}
К сожалению, все ответы на этот вопрос кажутся устаревшими (начиная с 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)
}
Будьте осторожны при использовании
kSecClassCertificate
чтобы очистить все, когда вы проводите модульное тестирование, используя Mac в качестве цели, так как это очистит ваш сертификат разработки. Вы можете просто отозвать существующий, но в конвейере CI/CD это не сработает.
Вы можете взглянуть на приложение KeyChain Access, которое находится в папке Utilities. Если вы запустите приложение и нажмете "Все элементы", оно должно отобразить все элементы, созданные вами на этом конкретном компьютере. Разработчики обычно начинают с ком.