Ma question concerne les porte-clés sous iOS (iPhone, iPad, ...). Je pense (mais je ne suis pas sûr) que l'implémentation de keychains sous Mac OS X soulève la même question avec la même réponse.
iOS fournit cinq types (classes) d'éléments de trousseau. Vous devez choisir l'une de ces cinq valeurs pour la clé kSecClass
afin de déterminer le type:
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)
Après une longue période de documentation des pommes de lecture, blogs et forum-entrées, j'ai découvert qu'un élément clé de type kSecClassGenericPassword
obtient son unicité des attributs kSecAttrAccessGroup
, kSecAttrAccount
et kSecAttrService
.
Si ces trois attributs dans la demande 1 sont les mêmes que dans la demande 2, vous recevez le même élément de trousseau de mot de passe générique, quels que soient les autres attributs. Si un (ou deux ou tous) de ces attributs modifie sa valeur, vous obtenez des éléments différents.
Mais kSecAttrService
n'est disponible que pour les éléments de type kSecClassGenericPassword
, donc il ne peut pas faire partie de la "clé unique" d'un élément d'un autre type, et il ne semble y avoir aucune documentation indiquant clairement quels attributs déterminent de manière unique un élément de trousseau.
L'exemple de code dans la classe «KeychainItemWrapper» de «GenericKeychain» utilise l'attribut kSecAttrGeneric
pour rendre un élément unique, mais il s'agit d'un bogue. Les deux entrées de cet exemple uniquement sont stockées sous la forme de deux entrées distinctes, car elles kSecAttrAccessGroup
sont différentes (l'une a le groupe d'accès défini, l'autre le laisse libre). Si vous essayez d'ajouter un deuxième mot de passe sans groupe d'accès, en utilisant Apple KeychainItemWrapper
, vous échouerez.
Alors, s'il vous plaît, répondez à mes questions:
- Est-il vrai que la combinaison de
kSecAttrAccessGroup
,kSecAttrAccount
etkSecAttrService
est la "clé unique" d'un élément de trousseau dont kSecClass estkSecClassGenericPassword
? - Quels attributs rendent un élément de trousseau unique si ce
kSecClass
n'est pas le caskSecClassGenericPassword
?
la source
Réponses:
Les clés primaires sont les suivantes (dérivées de fichiers open source d'Apple, voir Schema.m4 , KeySchema.m4 et SecItem.cpp ):
kSecClassGenericPassword
, la clé primaire est la combinaison dekSecAttrAccount
etkSecAttrService
.kSecClassInternetPassword
, la clé primaire est la combinaison dekSecAttrAccount
,kSecAttrSecurityDomain
,kSecAttrServer
,kSecAttrProtocol
,kSecAttrAuthenticationType
,kSecAttrPort
etkSecAttrPath
.kSecClassCertificate
, la clé primaire est la combinaison dekSecAttrCertificateType
,kSecAttrIssuer
etkSecAttrSerialNumber
.kSecClassKey
, la clé primaire est la combinaison dekSecAttrApplicationLabel
,kSecAttrApplicationTag
,kSecAttrKeyType
,kSecAttrKeySizeInBits
,kSecAttrEffectiveKeySize
, et le créateur, la date de début et de fin qui ne sont pas exposés par SecItem encore.kSecClassIdentity
je n'ai pas trouvé d'informations sur les champs de clé primaire dans les fichiers open source, mais comme une identité est la combinaison d'une clé privée et d'un certificat, je suppose que la clé primaire est la combinaison de la clé primaire champs pourkSecClassKey
etkSecClassCertificate
.Comme chaque élément du trousseau appartient à un groupe d'accès au trousseau, il semble que le groupe d'accès au trousseau (champ
kSecAttrAccessGroup
) est un champ ajouté à toutes ces clés primaires.la source
kSecClass
àkSecClassCertificate
oukSecClassKey
les contrôles porte - clés même si l'entrée (levalue
) est déjà enregistré. Cela empêche d'ajouter deux fois le même certificat ou la même clé. De plus, si vous spécifiez unekSecAttrApplicationTag
clé différente pour une clé (qui doit être unique, concernant le message ci-dessus), cela échouera.kSecClass
attribut comme le nom de la table et les valeurs spécifiées ci-dessus comme juste le nomprimary key
de la table respective.kSecAttrAccount
etkSecAttrService
? - ou le programmeur peut-il choisir une sémantique qu'elle décide?kSecAttrService
est pour stocker le service,kSecAttrAccount
est pour stocker le nom du compte. Vous pouvez y stocker différentes choses, mais cela peut prêter à confusion.J'ai rencontré un bug l'autre jour (sur iOS 7.1) lié à cette question. J'utilisais
SecItemCopyMatching
pour lire unkSecClassGenericPassword
article et il a continué à revenirerrSecItemNotFound
(-25300) même sikSecAttrAccessGroup
,kSecAttrAccount
etkSecAttrService
tous correspondaient à l'article dans le trousseau.Finalement, j'ai compris que
kSecAttrAccessible
cela ne correspondait pas. La valeur dans le trousseau contenait pdmn = dk (kSecAttrAccessibleAlways
), mais j'utilisaiskSecAttrAccessibleWhenUnlocked
.Bien sûr, cette valeur n'est pas nécessaire en premier lieu pour
SecItemCopyMatching
, mais ceOSStatus
n'était paserrSecParam
nierrSecBadReq
mais justeerrSecItemNotFound
(-25300), ce qui l'a rendu un peu difficile à trouver.Car
SecItemUpdate
j'ai rencontré le même problème, mais dans cette méthode, même utiliser la même chosekSecAttrAccessible
dans lequery
paramètre ne fonctionnait pas. Seule la suppression complète de cet attribut l'a corrigé.J'espère que ce commentaire sauvera quelques précieux moments de débogage pour certains d'entre vous.
la source
La réponse donnée par @Tammo Freese semble correcte (mais sans mentionner toutes les clés primaires). Je cherchais des preuves dans la documentation. Finalement trouvé:
Documentation Apple mentionnant les clés primaires pour chaque classe de secret (citation ci-dessous):
la source
Voici une autre information utile sur l'unicité d'un élément de trousseau, disponible dans la section «Assurer la recherche» de cette page de documentation Apple .
L'élément de classe a
kSecClassInternetPassword
été utilisé dans l'exemple, mais il y a une note qui dit:la source