2012-07-23 18 views
80

Sorumum, iOS'taki (iPhone, iPad, ...) anahtarlıklar ile ilgilidir. Bence (ama emin değilim) Mac OS X'in altındaki anahtarlıkların uygulanmasının aynı soruyu aynı soruyla gündeme getirdiğini düşünüyorum.Anahtarlık öğesini benzersiz yapan (iOS'ta) nedir?


iOS, beş tür (sınıf) anahtarlık öğesi sağlar. Sen türünü belirlemek için anahtar kSecClass için o beş değerden birini seçti gerekir: elma belgelerine, bloglar ve forum-girişlerini okuma uzun zaman sonra

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) 

, ben tip kSecClassGenericPassword bir anahtarlık öğesi alır öğrendim Öznitelikler kSecAttrAccessGroup, kSecAttrAccount ve kSecAttrService'dan farklıdır.

İstek 1'deki bu üç öznitelik, istek 2'dekiyle aynıysa, başka özniteliklere bakılmaksızın, aynı genel parola anahtarlık öğesini alırsınız. Bu özelliklerden biri (veya ikisi veya tamamı) değerini değiştirirse, farklı öğeler alırsınız.

Ancak kSecAttrService yalnızca kSecClassGenericPassword türündeki öğeler için kullanılabilir, bu nedenle başka türdeki bir öğenin "benzersiz anahtarının" bir parçası olamaz ve benzersiz olarak hangi nitelikleri açıkça işaret eden bir belge yok gibi görünüyor bir anahtarlık öğesi belirler.

"GenericKeychain" sınıfındaki "KeychainItemWrapper" sınıfındaki örnek kod, bir öğeyi benzersiz yapmak için kSecAttrGeneric özniteliğini kullanır, ancak bu bir hatadır. Bu örnekte yer alan iki giriş yalnızca iki ayrı giriş olarak saklanır, çünkü kSecAttrAccessGroup onlarınki farklıdır (biri erişim grubu kümesine sahiptir, diğeri serbest bırakır). Apple'ın KeychainItemWrapper'u kullanarak erişim grubu olmayan 2. şifreyi eklemeyi denerseniz, başarısız olursunuz.

Yani, benim sorulara cevap verin:

  • o kSecAttrAccessGroup, kSecAttrAccount ve kSecAttrService kombinasyonu kSecClass kSecClassGenericPassword bir anahtarlık öğenin "eşsiz anahtar" olduğu doğru mu?
  • kSecClasskSecClassGenericPassword değilse, hangi özellikler anahtarlık öğesini benzersiz kılar? aşağıdaki gibi
+1

Bu konuda bir [blog girişi] var (http://useyourloaf.com/blog/2010/04/28/keychain-duplicate-item-when-adding-password.html). – bobobobo

cevap

134

birincil anahtarlar vardır (Apple açık kaynak dosyalarından elde edilen, Schema.m4, KeySchema.m4 ve SecItem.cpp bakınız): sınıfının kSecClassGenericPassword bir anahtarlık öğe için

  • , birincil anahtar birleşimidir kSecAttrAccount ve kSecAttrService. sınıfın kSecClassInternetPassword bir anahtarlık öğe için
  • , birincil anahtar kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort ve kSecAttrPath birleşimidir.
  • kSecClassCertificate sınıfındaki bir anahtarlık öğesi için, birincil anahtar, kSecAttrCertificateType, kSecAttrIssuer ve kSecAttrSerialNumber'un birleşimidir.sınıfın kSecClassKey bir anahtarlık öğe için
  • , birincil anahtar kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType, kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize birleşimidir ve yaratıcısı, henüz SecItem tarafından maruz kalmaz tarih ve bitiş tarihi.
  • kSecClassIdentity sınıfındaki bir anahtarlık öğesi için açık kaynaklı dosyalardaki birincil anahtar alanlarıyla ilgili bilgi bulamadım, ancak kimlik özel bir anahtar ve bir sertifikanın birleşimidir, birincil anahtarın birleşim olduğunu varsayalım kSecClassKey ve kSecClassCertificate için birincil anahtar alanlarının.

her anahtarlık kalem anahtarlık erişim grubuna ait olarak, anahtarlık erişim grubu gibi hissediyor (alan kSecAttrAccessGroup) Bütün bu birincil anahtarlar için eklenen bir alandır.

+0

Gerçekten iyi bir cevap gibi geliyor! Teşekkür ederim! Ben kontrol edeceğim ve diğer kullanıcılardan ek yorumlar için bir veya iki gün beklemek istiyorum, ama sen +50 puan için sıcak bir adaysın. –

+3

Harika cevap! Sertifikalar ve özel anahtarlar için genel bir Keychain sarıcısı uygulamasında bazı günler için çalışıyorum. Bu, Apple'ın örnek kodunun yalnızca dize kimlik bilgilerini (kullanıcı adı/parola) depolayandan çok farklıdır. Ancak, 'kSecClass' 'kSecClassCertificate' veya 'kSecClassKey' olarak ayarladığınızda, anahtarın ("value") zaten kayıtlı olup olmadığını da kontrol ettiğini öğrendim. Bu aynı sertifikayı veya anahtarı iki kez eklemekten kaçınır. Ayrıca bir anahtar için farklı bir "kSecAttrApplicationTag" belirtirseniz (yukarıdaki iletiyle ilgili benzersiz olması gereken), başarısız olur. – Chris

+0

@Chris Bu ek kontrol hakkında bilmek güzel, teşekkürler! –

7

Bu soruyla ilgili olarak geçen gün (iOS 7.1'de) bir hata yapıyordum. kSecClassGenericPassword öğeyi okumak için SecItemCopyMatching kullanıyordum ve kSecAttrAccessGroup, kSecAttrAccount ve kSecAttrService öğelerinin tümü anahtarlıktaki öğelerle eşleşiyor olsa bile errSecItemNotFound (-25300) dönmeye devam etti.

Sonunda, kSecAttrAccessible'un eşleşmediğini anladım. Anahtar zincirindeki değer pdmn = dk (kSecAttrAccessibleAlways) olarak tutuldu, ancak kSecAttrAccessibleWhenUnlocked kullanıyordum.

Tabii bu değer SecItemCopyMatching için ilk etapta gerekli, ancak OSStatus değil errSecParam ne de errSecBadReq ama sadece errSecItemNotFound (-25300) o yapılan biraz zor bulmaktı değildir.

SecItemUpdate için Ben aynı sorunu yaşadım, ancak query parametresinde aynı kSecAttrAccessible parametresini kullanarak bile bu yöntem işe yaramadı. Sadece bu özelliği kaldırmak tamamen düzeltildi.

Bu yorumun bazılarınız için birkaç değerli hata ayıklama anı biriktireceğini umuyorum.

İlgili konular