Bir anahtarlık öğesini benzersiz kılan nedir (iOS'ta)?


104

Sorum iOS'taki (iPhone, iPad, ...) anahtar zincirleriyle ilgili. Mac OS X altında anahtar zincirlerinin uygulanmasının aynı soruyu aynı cevapla gündeme getirdiğini düşünüyorum (ama emin değilim).


iOS, beş tür (sınıf) anahtar zinciri öğesi sağlar. Türünü kSecClassbelirlemek için anahtar için şu beş değerden birini seçmelisiniz :

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)

Okuma elma dokümantasyon, bloglar ve forum-girişlerinin uzun süre sonra türde bir anahtarlık kalem öğrendim kSecClassGenericPasswordnitelikler onun benzersizliğini alır kSecAttrAccessGroup, kSecAttrAccountve kSecAttrService.

Talep 1'deki bu üç öznitelik, istek 2'deki ile aynıysa, diğer özniteliklerden bağımsız olarak aynı genel parola anahtar zinciri öğesini alırsınız. Bu özelliklerden biri (veya ikisi veya tümü) değerini değiştirirse, farklı öğeler alırsınız.

Ancak kSecAttrServiceyalnızca türdeki öğeler için mevcuttur kSecClassGenericPassword, bu nedenle başka türden bir öğenin "benzersiz anahtarının" parçası olamaz ve hangi özelliklerin bir anahtar zinciri öğesini benzersiz şekilde belirlediğini açıkça gösteren hiçbir belge yok gibi görünüyor.

"GenericKeychain" in "KeychainItemWrapper" sınıfındaki örnek kod, kSecAttrGenericbir öğeyi benzersiz kılmak için özniteliği kullanır , ancak bu bir hatadır. Bu örnekteki iki giriş yalnızca iki ayrı giriş olarak saklanır, çünkü bunların kSecAttrAccessGroupfarklıdır (biri erişim grubu setine sahip, diğeri serbest bırakıyor). Apple'ı kullanarak erişim grubu olmadan 2. bir parola eklemeye çalışırsanız KeychainItemWrapperbaşarısız olursunuz.

Lütfen sorularıma cevap verin:

  • O, doğru mu bu kombinasyonu kSecAttrAccessGroup, kSecAttrAccountve kSecAttrServicekSecClass bir anahtarlık öğenin "eşsiz anahtar" dır kSecClassGenericPassword?
  • Onun ise hangi nitelikleri bir anahtarlık öğesi eşsiz kılan kSecClassdeğil kSecClassGenericPassword?

1
Burada bununla ilgili bir blog girişi var .
bobobobo

Yanıtlar:


179

Birincil anahtarlar aşağıdaki gibidir (Apple'dan açık kaynak dosyalarından türetilmiştir, bkz. Schema.m4 , KeySchema.m4 ve SecItem.cpp ):

  • Sınıfın bir anahtarlık öğe için kSecClassGenericPassword, birincil anahtar birleşimidir kSecAttrAccountve kSecAttrService.
  • Sınıfın bir anahtarlık öğe için kSecClassInternetPassword, birincil anahtar birleşimidir kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPortve kSecAttrPath.
  • Sınıfın bir anahtarlık öğe için kSecClassCertificate, birincil anahtar birleşimidir kSecAttrCertificateType, kSecAttrIssuerve kSecAttrSerialNumber.
  • Sınıfın bir anahtarlık öğe için kSecClassKey, birincil anahtar birleşimidir kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType, kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize, ve yaratıcısı, henüz SecItem tarafından maruz kalmaz tarih ve bitiş tarihi.
  • Sınıfın bir anahtar zinciri öğesi kSecClassIdentityiçin, açık kaynak dosyalardaki birincil anahtar alanları hakkında bilgi bulamadım, ancak kimlik bir özel anahtar ve bir sertifikanın birleşimi olduğundan, birincil anahtarın birincil anahtarın birleşimi olduğunu varsayıyorum alanları için kSecClassKeyve kSecClassCertificate.

Her bir anahtar zinciri öğesi bir anahtar zinciri erişim grubuna ait olduğundan, anahtar zinciri erişim grubu (alanı kSecAttrAccessGroup) tüm bu birincil anahtarlara eklenmiş bir alan gibi görünüyor.


Gerçekten iyi bir cevap gibi görünüyor! Teşekkür ederim! Kontrol edeceğim ve diğer kullanıcılardan ek yorumlar için bir veya iki gün beklemek istiyorum, ancak ödülden +50 puan için sıcak bir adaysınız.
Hubert Schölnast

3
Mükemmel cevap! Sertifikalar ve özel anahtarlar için genel bir Anahtar Zinciri sarmalayıcısı uygulamak için birkaç gündür çalışıyorum. Bu, Apple'ın yalnızca dize kimlik bilgilerini (kullanıcı adı / parola) saklayan örnek kodundan çok farklıdır. Ancak, ben ayarladığınız zaman öğrendim kSecClassetmek kSecClassCertificateveya kSecClassKeyayrıca Anahtarlık denetler giriş (eğer value) zaten saklanır. Bu, aynı sertifikayı veya anahtarı iki kez eklemeyi engeller. Ayrıca kSecAttrApplicationTagbir anahtar için farklı bir anahtar belirtirseniz (yukarıdaki gönderiye göre benzersiz olması gerekir) başarısız olur.
Chris

1
kSecClassÖzniteliği tablo adı olarak ve yukarıda belirtilen değerleri sadece ilgili tablonun adı olarak düşünmek yardımcı olabilir primary key.
bobobobo

2
Arasında semantik nedir kSecAttrAccountve kSecAttrService? - ya da programcı karar verdiği herhangi bir anlambilim seçebilir mi?
wcochran

1
kSecAttrServiceservisi kSecAttrAccountdepolamak içindir, hesap adını saklamak içindir. İçlerinde farklı şeyler saklayabilirsiniz, ancak bu kafa karıştırıcı olabilir.
Tammo Freese

9

Geçen gün (iOS 7.1'de) bu soruyla ilgili bir hataya çarpıyordum. Ben kullanıyordum SecItemCopyMatchingbir okuma kSecClassGenericPasswordöğeyi ve dönen tuttu errSecItemNotFoundrağmen (-25300) kSecAttrAccessGroup, kSecAttrAccountve kSecAttrServicetüm anahtarlıkta öğeyi eşleşen bulundu.

Sonunda kSecAttrAccessiblebunun uyuşmadığını anladım . Anahtar zincirindeki değer pdmn = dk ( kSecAttrAccessibleAlways) tutuyordu , ancak kullanıyordum kSecAttrAccessibleWhenUnlocked.

Tabii bu değer için ilk etapta gerekli değildir SecItemCopyMatching, ancak OSStatusdeğildi errSecParamne de errSecBadReqama sadece errSecItemNotFound(-25300) o biraz zor bulmak için yapılan hangi.

İçin SecItemUpdateben aynı sorunu yaşadı ama bu yöntemde hatta aynı kullanarak var kSecAttrAccessibleiçinde queryparametresi çalışma yoktu. Sadece bu özelliği tamamen kaldırmak sorunu çözdü.

Umarım bu yorum, bazılarınız için birkaç değerli hata ayıklama anını kurtarır.


4

@Tammo Freese tarafından verilen cevap doğru görünüyor (ancak tüm birincil anahtarlardan bahsetmiyor). Belgelerde bazı kanıtlar arıyordum. Nihayet bulundu:

Her bir sır sınıfı için birincil anahtarlardan bahseden Apple Belgeleri (aşağıda alıntı):

Sistem, bir anahtar zincirinde aynı bileşik birincil anahtar setine sahip aynı sınıftan bir öğeye zaten sahipse, bir öğeyi belirli bir anahtar zincirinin kopyası olarak kabul eder. Her anahtar zinciri öğesi sınıfının farklı bir birincil anahtar seti vardır, ancak birkaç özellik tüm sınıflarda ortak olarak kullanılır. Özellikle, uygun olduğu yerlerde, kSecAttrSynchronizable ve kSecAttrAccessGroup birincil anahtarlar kümesinin parçalarıdır . Sınıf başına ek birincil anahtarlar aşağıda listelenmiştir:

  • Genel parolalar için birincil anahtarlar arasında kSecAttrAccount ve kSecAttrService bulunur.
  • İnternet parolaları için birincil anahtarlar arasında kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort ve kSecAttrPath bulunur.
  • Sertifikalar için birincil anahtarlar arasında kSecAttrCertificateType, kSecAttrIssuer ve kSecAttrSerialNumber bulunur.
  • Anahtar öğeler için birincil anahtarlar arasında kSecAttrKeyClass, kSecAttrKeyType, kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeySizeInBits ve kSecAttrEffectiveKeySize bulunur.
  • Birlikte paketlenmiş bir sertifika ve özel anahtar olan kimlik öğeleri için birincil anahtarlar, sertifika ile aynıdır. Bir özel anahtar birden çok kez onaylanabileceğinden, sertifikanın benzersizliği kimliğin kimliğini belirler.

Bu bağlantı soruyu cevaplayabilirken, cevabın temel kısımlarını buraya eklemek ve referans için bağlantıyı sağlamak daha iyidir. Bağlantılı sayfa değişirse, yalnızca bağlantı yanıtları geçersiz hale gelebilir. - Yorumdan
pwc

bu durumda tüm bağlantının kopyalanması anlamına gelmesine rağmen kabul etti.
Julian Król

0

Bu Apple belgeleri sayfasının "Aranabilirliği Sağlayın" bölümünde bulunan bir anahtarlık öğesinin benzersizliği hakkında başka bir yararlı bilgi .

Öğeyi daha sonra bulabilmek için, nitelikleri hakkındaki bilginizi kullanacaksınız. Bu örnekte, sunucu ve hesap, öğenin ayırt edici özellikleridir. Sabit nitelikler için (burada, sunucu), arama sırasında aynı değeri kullanın. Bunun aksine, hesap özelliği dinamiktir çünkü çalışma zamanında kullanıcı tarafından sağlanan bir değeri tutar. Uygulamanız hiçbir zaman farklı özelliklere sahip benzer öğeler eklemediği sürece (aynı sunucudaki farklı hesaplar için şifreler gibi), bu dinamik özellikleri arama parametreleri olarak çıkarabilir ve bunun yerine öğeyle birlikte alabilirsiniz. Sonuç olarak, şifreyi aradığınızda, ilgili kullanıcı adını da alırsınız.

Uygulamanız değişen dinamik özelliklere sahip öğeler eklerse, alma sırasında bunlar arasından seçim yapmanın bir yolunu bulmanız gerekir. Seçeneklerden biri, öğeler hakkındaki bilgileri başka bir şekilde kaydetmektir. Örneğin, bir Çekirdek Veri modelinde kullanıcıların kayıtlarını tutarsanız, şifre alanını depolamak için anahtar zinciri hizmetlerini kullandıktan sonra kullanıcı adını orada saklarsınız. Daha sonra, parola aramayı koşullandırmak için veri modelinizden alınan kullanıcı adını kullanırsınız.

Diğer durumlarda, daha fazla öznitelik ekleyerek öğeyi daha fazla karakterize etmek mantıklı olabilir. Örneğin kSecAttrLabel, öğeyi belirli bir amaç için işaretleyen bir dize sağlayarak , özniteliği orijinal ekleme sorgusuna dahil edebilirsiniz . Ardından, aramanızı daha sonra daraltmak için bu özelliği kullanabilirsiniz.

kSecClassInternetPasswordÖrnekte sınıf öğesi kullanıldı, ancak şunu belirten bir not var:

Anahtar zinciri hizmetleri ayrıca ilgili kSecClassGenericPassword öğe sınıfını sunar. Genel parolalar çoğu bakımdan İnternet parolalarına benzer, ancak uzaktan erişime özgü belirli özniteliklerden yoksundur (örneğin, kSecAttrServer özniteliğine sahip değillerdir). Bu ekstra özelliklere ihtiyacınız olmadığında, bunun yerine genel bir şifre kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.