Как удалить все элементы цепочки для ключей, доступные для приложения?

У меня есть случайные элементы цепочки для ключей на 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. Если вы запустите приложение и нажмете "Все элементы", оно должно отобразить все элементы, созданные вами на этом конкретном компьютере. Разработчики обычно начинают с ком.

Другие вопросы по тегам