Meine Frage betrifft Schlüsselanhänger in iOS (iPhone, iPad, ...). Ich denke (bin mir aber nicht sicher), dass die Implementierung von Schlüsselanhängern unter Mac OS X dieselbe Frage mit derselben Antwort aufwirft.
iOS bietet fünf Arten (Klassen) von Schlüsselbundelementen. Sie müssen einen dieser fünf Werte für den Schlüssel auswählen kSecClass
, um den Typ zu bestimmen:
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)
Nach langer Zeit des Lesens Äpfel Dokumentation, Blogs und Forum-Einträge, fand ich heraus , dass ein Schlüsselbund Artikel vom Typ kSecClassGenericPassword
seine Einzigartigkeit aus den Attributen wird kSecAttrAccessGroup
, kSecAttrAccount
und kSecAttrService
.
Wenn diese drei Attribute in Anforderung 1 mit denen in Anforderung 2 identisch sind, erhalten Sie unabhängig von anderen Attributen dasselbe generische Kennwort-Schlüsselbundelement. Wenn eines (oder zwei oder alle) dieser Attribute seinen Wert ändert, erhalten Sie verschiedene Elemente.
Ist kSecAttrService
jedoch nur für Artikel vom Typ verfügbar kSecClassGenericPassword
, kann es also nicht Teil des "eindeutigen Schlüssels" eines Artikels eines anderen Typs sein, und es scheint keine Dokumentation zu geben, die klar darauf hinweist, welche Attribute einen Schlüsselbundartikel eindeutig bestimmen.
Der Beispielcode in der Klasse "KeychainItemWrapper" von "GenericKeychain" verwendet das Attribut kSecAttrGeneric
, um ein Element eindeutig zu machen. Dies ist jedoch ein Fehler. Die beiden Einträge in diesem Beispiel werden nur als zwei unterschiedliche Einträge gespeichert, da sie kSecAttrAccessGroup
unterschiedlich sind (bei einem ist die Zugriffsgruppe festgelegt, bei dem anderen ist sie frei). Wenn Sie versuchen, mit Apple ein zweites Kennwort ohne Zugriffsgruppe hinzuzufügen, schlagen KeychainItemWrapper
Sie fehl.
Beantworten Sie also bitte meine Fragen:
- Ist es wahr, dass die Kombination aus
kSecAttrAccessGroup
,kSecAttrAccount
undkSecAttrService
sind die „eindeutigen Schlüssel“ ein Schlüsselanhänger - Elements , dessen kSecClass istkSecClassGenericPassword
? - Welche Attribute machen ein Schlüsselbundelement einzigartig, wenn dies
kSecClass
nicht der Fall istkSecClassGenericPassword
?
quelle
Antworten:
Die Primärschlüssel lauten wie folgt (abgeleitet von Open Source-Dateien von Apple, siehe Schema.m4 , KeySchema.m4 und SecItem.cpp ):
kSecClassGenericPassword
ist der Primärschlüssel die Kombination vonkSecAttrAccount
undkSecAttrService
.kSecClassInternetPassword
, ist der Primärschlüssel die Kombination vonkSecAttrAccount
,kSecAttrSecurityDomain
,kSecAttrServer
,kSecAttrProtocol
,kSecAttrAuthenticationType
,kSecAttrPort
undkSecAttrPath
.kSecClassCertificate
, ist der Primärschlüssel die Kombination auskSecAttrCertificateType
,kSecAttrIssuer
undkSecAttrSerialNumber
.kSecClassKey
, ist der Primärschlüssel die Kombination vonkSecAttrApplicationLabel
,kSecAttrApplicationTag
,kSecAttrKeyType
,kSecAttrKeySizeInBits
,kSecAttrEffectiveKeySize
, und der Schöpfer, und Enddatum beginnen , die von SecItem noch nicht ausgesetzt sind.kSecClassIdentity
ich keine Informationen zu den Primärschlüsselfeldern in den Open Source-Dateien gefunden, aber da eine Identität die Kombination eines privaten Schlüssels und eines Zertifikats ist, gehe ich davon aus, dass der Primärschlüssel die Kombination des Primärschlüssels ist Felder fürkSecClassKey
undkSecClassCertificate
.Da jedes Schlüsselbundelement zu einer Schlüsselbundzugriffsgruppe gehört, scheint die Schlüsselbundzugriffsgruppe (Feld
kSecAttrAccessGroup
) ein zusätzliches Feld zu all diesen Primärschlüsseln zu sein.quelle
kSecClass
vonkSecClassCertificate
oderkSecClassKey
Schlüsselbund auch überprüft wird, ob der Eintrag (dervalue
) bereits gespeichert ist. Dies verhindert, dass dasselbe Zertifikat oder Schlüssel zweimal hinzugefügt wird. Auch wenn SiekSecAttrApplicationTag
für einen Schlüssel einen anderen angeben (der in Bezug auf den obigen Beitrag eindeutig sein muss), schlägt dies fehl.kSecClass
Attribut als Tabellennamen und die oben angegebenen Werte nur als dieprimary key
der jeweiligen Tabelle vorzustellen.kSecAttrAccount
undkSecAttrService
? - oder kann der Programmierer eine Semantik wählen, die er entscheidet?kSecAttrService
dient zum Speichern des Dienstes,kSecAttrAccount
dient zum Speichern des Kontonamens. Sie könnten verschiedene Dinge darin speichern, aber das kann verwirrend werden.Ich habe neulich (unter iOS 7.1) einen Fehler gefunden, der mit dieser Frage zusammenhängt. Ich
SecItemCopyMatching
habe einenkSecClassGenericPassword
Artikel gelesen und er kehrte immer wieder zurückerrSecItemNotFound
(-25300)kSecAttrAccessGroup
,kSecAttrAccount
undkSecAttrService
alle stimmten mit dem Artikel im Schlüsselbund überein.Schließlich fand ich heraus, dass
kSecAttrAccessible
das nicht passte. Der Wert im Schlüsselbund enthielt pdmn = dk (kSecAttrAccessibleAlways
), aber ich habe ihn verwendetkSecAttrAccessibleWhenUnlocked
.Natürlich wird dieser Wert überhaupt nicht benötigt
SecItemCopyMatching
, aber dasOSStatus
war nichterrSecParam
noch,errSecBadReq
sondern nurerrSecItemNotFound
(-25300), was es etwas schwierig machte, ihn zu finden.Denn
SecItemUpdate
ich habe das gleiche Problem erlebt, aber bei dieser Methode hat es nicht funktioniert, dasselbekSecAttrAccessible
imquery
Parameter zu verwenden. Nur das vollständige Entfernen dieses Attributs hat es behoben.Ich hoffe, dieser Kommentar erspart einigen von Ihnen einige wertvolle Debugging-Momente.
quelle
Die Antwort von @Tammo Freese scheint richtig zu sein (ohne jedoch alle Primärschlüssel zu erwähnen). Ich habe nach Beweisen in der Dokumentation gesucht. Endlich gefunden:
Apple-Dokumentation mit Erwähnung der Primärschlüssel für jede Klasse von Geheimnissen (Zitat unten):
quelle
Im Folgenden finden Sie weitere nützliche Informationen zur Eindeutigkeit eines Schlüsselbundelements im Abschnitt "Suchbarkeit sicherstellen" auf dieser Apple-Dokumentseite .
kSecClassInternetPassword
Im Beispiel wurde ein Klassengegenstand verwendet, aber es gibt einen Hinweis, der besagt:quelle