Pertanyaan saya menyangkut gantungan kunci di iOS (iPhone, iPad, ...). Saya pikir (tapi saya tidak yakin) bahwa penerapan gantungan kunci di bawah Mac OS X menimbulkan pertanyaan yang sama dengan jawaban yang sama.
iOS menyediakan lima jenis (kelas) item rantai kunci. Anda harus memilih salah satu dari lima nilai kunci kSecClass
untuk menentukan jenis:
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)
Setelah sekian lama membaca dokumentasi apel, blog, dan entri forum, saya menemukan bahwa jenis item gantungan kunci kSecClassGenericPassword
mendapatkan keunikannya dari atribut kSecAttrAccessGroup
, kSecAttrAccount
dan kSecAttrService
.
Jika ketiga atribut dalam permintaan 1 sama dengan permintaan 2, Anda akan menerima item rantai kunci kata sandi umum yang sama, terlepas dari atribut lainnya. Jika satu (atau dua atau semua) atribut ini mengubah nilainya, Anda akan mendapatkan item yang berbeda.
Namun kSecAttrService
hanya tersedia untuk item jenis kSecClassGenericPassword
, sehingga tidak dapat menjadi bagian dari "kunci unik" item jenis lain, dan tampaknya tidak ada dokumentasi yang menunjukkan dengan jelas atribut mana yang secara unik menentukan item rantai kunci.
Kode contoh di kelas "KeychainItemWrapper" dari "GenericKeychain" menggunakan atribut kSecAttrGeneric
untuk membuat item menjadi unik, tetapi ini adalah bug. Dua entri dalam contoh ini hanya disimpan sebagai dua entri berbeda, karena keduanya kSecAttrAccessGroup
berbeda (satu memiliki kumpulan grup akses, yang lain membiarkannya gratis). Jika Anda mencoba menambahkan kata sandi kedua tanpa grup akses, menggunakan kata sandi Apple KeychainItemWrapper
, Anda akan gagal.
Jadi, tolong jawab pertanyaan saya:
- Apakah benar, bahwa kombinasi
kSecAttrAccessGroup
,kSecAttrAccount
dankSecAttrService
merupakan "kunci unik" dari item rantai kunci yang kSecClass-nyakSecClassGenericPassword
? - Atribut mana yang membuat item rantai kunci unik jika
kSecClass
tidakkSecClassGenericPassword
?
sumber
Jawaban:
Kunci utama adalah sebagai berikut (berasal dari file open source dari Apple, lihat Schema.m4 , KeySchema.m4 dan SecItem.cpp ):
kSecClassGenericPassword
, kunci utamanya adalah kombinasi darikSecAttrAccount
dankSecAttrService
.kSecClassInternetPassword
, kunci utama adalah kombinasikSecAttrAccount
,kSecAttrSecurityDomain
,kSecAttrServer
,kSecAttrProtocol
,kSecAttrAuthenticationType
,kSecAttrPort
dankSecAttrPath
.kSecClassCertificate
, kunci utamanya adalah kombinasi darikSecAttrCertificateType
,kSecAttrIssuer
dankSecAttrSerialNumber
.kSecClassKey
, kunci utama adalah kombinasikSecAttrApplicationLabel
,kSecAttrApplicationTag
,kSecAttrKeyType
,kSecAttrKeySizeInBits
,kSecAttrEffectiveKeySize
, dan pencipta, mulai tanggal dan tanggal akhir yang tidak terpapar oleh SecItem belum.kSecClassIdentity
saya belum menemukan info di bidang kunci utama di file sumber terbuka, tetapi karena identitas adalah kombinasi dari kunci pribadi dan sertifikat, saya menganggap kunci utama adalah kombinasi dari kunci utama bidang untukkSecClassKey
dankSecClassCertificate
.Karena setiap item rantai kunci termasuk dalam grup akses rantai kunci, rasanya grup akses rantai kunci (bidang
kSecAttrAccessGroup
) adalah bidang yang ditambahkan ke semua kunci utama ini.sumber
kSecClass
kekSecClassCertificate
ataukSecClassKey
rantai kunci juga memeriksa apakah entri (thevalue
) sudah disimpan. Ini mencegah penambahan sertifikat atau kunci yang sama dua kali. Juga jika Anda menentukankSecAttrApplicationTag
kunci yang berbeda (yang harus unik, berkenaan dengan posting di atas) itu akan gagal.kSecClass
atribut sebagai nama tabel , dan nilai yang ditentukan di atas hanya sebagaiprimary key
tabel masing-masing.kSecAttrAccount
dankSecAttrService
? - atau dapatkah programmer memilih semantik yang dia putuskan?kSecAttrService
adalah untuk menyimpan layanan,kSecAttrAccount
untuk menyimpan nama akun. Anda dapat menyimpan berbagai hal di dalamnya, tetapi itu mungkin membingungkan.Saya terkena bug beberapa hari yang lalu (di iOS 7.1) yang terkait dengan pertanyaan ini. Saya menggunakan
SecItemCopyMatching
untuk membacakSecClassGenericPassword
item dan itu terus kembalierrSecItemNotFound
(-25300) meskipunkSecAttrAccessGroup
,kSecAttrAccount
dankSecAttrService
semuanya cocok dengan item di gantungan kunci.Akhirnya saya menemukan bahwa
kSecAttrAccessible
itu tidak cocok. Nilai di rantai kunci dipegang pdmn = dk (kSecAttrAccessibleAlways
), tetapi saya menggunakankSecAttrAccessibleWhenUnlocked
.Tentu saja nilai ini tidak diperlukan di tempat pertama untuk
SecItemCopyMatching
, tetapiOSStatus
bukanerrSecParam
atauerrSecBadReq
melainkan hanyaerrSecItemNotFound
(-25300) yang membuatnya agak sulit untuk ditemukan.Untuk
SecItemUpdate
saya telah mengalami masalah yang sama tetapi dalam metode ini bahkan menggunakan yang samakSecAttrAccessible
dalamquery
parameter tidak bekerja. Hanya menghapus sepenuhnya atribut ini yang memperbaikinya.Saya harap komentar ini akan menghemat beberapa momen debugging yang berharga bagi sebagian dari Anda.
sumber
Jawaban yang diberikan oleh @Tammo Freese sepertinya benar (tapi tidak menyebut semua kunci utama). Saya sedang mencari beberapa bukti di dokumentasi. Akhirnya ketemu:
Dokumentasi Apple menyebutkan kunci utama untuk setiap kelas rahasia (kutipan di bawah):
sumber
Berikut ini adalah informasi berguna lainnya tentang keunikan item rantai kunci, yang dapat ditemukan di bagian "Pastikan Kemampuan Pencarian" di halaman dokumen Apple ini .
Item kelas
kSecClassInternetPassword
digunakan dalam contoh ini, tetapi ada catatan yang mengatakan:sumber