Мой вопрос касается брелков в iOS (iPhone, iPad, ...). Я думаю (но не уверен), что реализация связок ключей в Mac OS X поднимает тот же вопрос с тем же ответом.
iOS предоставляет пять типов (классов) элементов связки ключей. Вы должны выбрать одно из этих пяти значений ключа, kSecClass
чтобы определить тип:
kSecClassGenericPassword used to store a generic password
kSecClassInternetPassword used to store an internet password
kSecClassCertificate used to store a certificate
kSecClassKey used to store a kryptographic key
kSecClassIdentity used to store an identity (certificate + private key)
После долгого чтения документации Apple, блогов и записей на форумах, я обнаружил, что элемент цепочки для ключей kSecClassGenericPassword
получает свою уникальность от атрибутов kSecAttrAccessGroup
, kSecAttrAccount
и kSecAttrService
.
Если эти три атрибута в запросе 1 такие же, как в запросе 2, то вы получите тот же элемент цепочки ключей общего пароля, независимо от любых других атрибутов. Если один (два или все) из этих атрибутов изменяет свое значение, вы получаете разные элементы.
Но kSecAttrService
он доступен только для элементов типа kSecClassGenericPassword
, поэтому он не может быть частью «уникального ключа» элемента любого другого типа, и, похоже, нет документации, которая четко указывает, какие атрибуты однозначно определяют элемент цепочки для ключей.
Пример кода в классе «KeychainItemWrapper» из «GenericKeychain» использует атрибут, kSecAttrGeneric
чтобы сделать элемент уникальным, но это ошибка. Только две записи в этом примере хранятся как две отдельные записи, потому что они kSecAttrAccessGroup
разные (одна имеет группу доступа, другая позволяет освободить). Если вы попытаетесь добавить второй пароль без группы доступа, используя Apple KeychainItemWrapper
, у вас ничего не получится.
Итак, ответьте, пожалуйста, на мои вопросы:
- Верно ли, что сочетание
kSecAttrAccessGroup
,kSecAttrAccount
иkSecAttrService
это «уникальный ключ» из брелка элемента которого kSecClass этоkSecClassGenericPassword
? - Какие атрибуты делают элемент цепочки для ключей уникальным, если
kSecClass
это не такkSecClassGenericPassword
?
источник
Ответы:
Основные ключи следующие (получены из файлов с открытым исходным кодом от Apple, см. Schema.m4 , KeySchema.m4 и SecItem.cpp ):
kSecClassGenericPassword
первичный ключ - это комбинацияkSecAttrAccount
иkSecAttrService
.kSecClassInternetPassword
, первичный ключ является комбинациейkSecAttrAccount
,kSecAttrSecurityDomain
,kSecAttrServer
,kSecAttrProtocol
,kSecAttrAuthenticationType
,kSecAttrPort
иkSecAttrPath
.kSecClassCertificate
первичным ключом является комбинацияkSecAttrCertificateType
,kSecAttrIssuer
иkSecAttrSerialNumber
.kSecClassKey
, первичный ключ является комбинациейkSecAttrApplicationLabel
,kSecAttrApplicationTag
,kSecAttrKeyType
,kSecAttrKeySizeInBits
,kSecAttrEffectiveKeySize
, и создатель, дата начала и дата окончания , которые не подвергаются по SecItem еще.kSecClassIdentity
я не нашел информации о полях первичного ключа в файлах с открытым исходным кодом, но поскольку идентификатор - это комбинация закрытого ключа и сертификата, я предполагаю, что первичный ключ - это комбинация первичного ключа поля дляkSecClassKey
иkSecClassCertificate
.Поскольку каждый элемент цепочки для ключей принадлежит к группе доступа цепочки для ключей, создается впечатление, что группа (поле
kSecAttrAccessGroup
) доступа цепочки для ключей является добавленным полем ко всем этим первичным ключам.источник
kSecClass
значениеkSecClassCertificate
или,kSecClassKey
Связка ключей также проверяет, сохранена ли уже запись (value
). Это предотвращает добавление одного и того же сертификата или ключа дважды. Также, если вы укажете другойkSecAttrApplicationTag
ключ (который должен быть уникальным, как указано в сообщении выше), это не сработает.kSecClass
атрибуте как об имени таблицы , а указанные выше значения - как об атрибутеprimary key
соответствующей таблицы.kSecAttrAccount
иkSecAttrService
? - или может программист выбрать любую семантику, которую он решит?kSecAttrService
для хранения службы,kSecAttrAccount
для хранения имени учетной записи. В них можно хранить разные вещи, но это может запутать.На днях я обнаружил ошибку (в iOS 7.1), связанную с этим вопросом. Я использовал
SecItemCopyMatching
, чтобы прочитатьkSecClassGenericPassword
элемент , и он постоянно возвращалсяerrSecItemNotFound
(-25300) , хотяkSecAttrAccessGroup
,kSecAttrAccount
иkSecAttrService
были все соответствующие пункт в связке ключей.В конце концов я понял, что
kSecAttrAccessible
это не соответствует. Значение в связке ключей содержало pdmn = dk (kSecAttrAccessibleAlways
), но я использовалkSecAttrAccessibleWhenUnlocked
.Конечно, это значение в первую очередь не нужно для
SecItemCopyMatching
, ноOSStatus
не былоerrSecParam
ниerrSecBadReq
а простоerrSecItemNotFound
(-25300) , который сделал это немного сложно найти.Потому
SecItemUpdate
что у меня возникла та же проблема, но в этом методе даже использование того же параметраkSecAttrAccessible
вquery
параметре не сработало. Только полное удаление этого атрибута исправило его.Я надеюсь, что этот комментарий сэкономит несколько драгоценных моментов отладки для некоторых из вас.
источник
Ответ @Tammo Freese кажется правильным (но без упоминания всех первичных ключей). Я искал доказательства в документации. Наконец-то нашел:
Документация Apple, в которой указаны первичные ключи для каждого класса секретов (цитата ниже):
источник
Вот еще одна полезная информация об уникальности элемента связки ключей, которую можно найти в разделе «Обеспечение возможности поиска» на этой странице документации Apple .
В
kSecClassInternetPassword
примере использовался элемент класса , но есть примечание, в котором говорится:источник