Keychain — iOS, watchOS, macOS va tvOS-da apparat darajasida parollar, kalitlar va sertifikatlarni boshqaradigan himoyalangan hisob ma'lumotlari omboridir. UserDefaults-dan farqli o'laroq, Keychain-dagi ma'lumotlar shifrlanadi va ilova sandboxi bilan izolyatsiya qilinadi. Apple Developer Documentation-ga ko'ra, Keychain maxfiy ma'lumotlarni himoya qilish uchun Secure Enclave mexanizmlari va AES-256 apparat shifrlashidan foydalanadi.
Asosiy fikrlar
Keychain — Apple operatsion tizimining parollar, kriptografik kalitlar, sertifikatlar va boshqa maxfiy ma'lumotlarni xavfsiz saqlash uchun mo'ljallangan xavfsiz ma'lumotlar bazasidir. Keychain birinchi marta 1999-yilda Mac OS 8.6 da, iOS-da esa birinchi SDK versiyasidan paydo bo'lgan.
Keychain mobil dasturlashning asosiy muammosini hal qiladi: himoyalanmagan fayl tizimida sirlarni (tokenlar, parollar, shifrlash kalitlari) saqlash. UserDefaults yoki SQLite-dan farqli o'laroq, Keychain-dagi ma'lumotlar shifrlangan shaklda saqlanadi va diskka yozilganda avtomatik shifrlanadi.
Har bir iOS ilovasi izolyatsiyalangan sandboxda ishlaydi va faqat o'z keychain-iga kirish huquqiga ega. Biroq dasturchi keychain access groups orqali bir dasturchining ilovalari o'rtasida Keychain-ga umumiy kirishni sozlashi mumkin. iCloud Keychain foydalanuvchisi qo'shimcha ravishda ma'lumotlarni qurilmalar o'rtasida end-to-end shifrlash orqali sinxronlashtiradi.
Apple Security White Paper (2025)-ga ko'ra, Keychain qurilmaning noyob identifikatoriga (UID) bog'langan kalit bilan AES-256 apparat shifrlashidan foydalanadi, bu ma'lumotlarni qurilmadan olinganda erishib bo'lmas qiladi.
Keychain darajali xizmat sifatida ishlaydi: ilova Security framework-ga murojaat qiladi, u shifrlangan SQLite Keychain bazasini boshqaruvchi securityd demoni bilan o'zaro aloqada bo'ladi. Har bir yozuv alohida kalit bilan shifrlanadi, kalitlarning o'zi esa A7 chipi va undan yangi qurilmalarda Secure Enclave apparat moduli bilan himoyalanadi.
Security framework Keychain Services bilan ishlash uchun C interfeysini taqdim etadi. Asosiy funksiyalar: SecItemAdd (qo'shish), SecItemCopyMatching (qidirish), SecItemUpdate (yangilash) va SecItemDelete (o'chirish). Har bir operatsiya so'rov turini tavsiflovchi CFDictionaryRef atributlar lug'atini qabul qiladi.
Ma'lumotlar sinflarga ko'ra tasniflanadi: kSecClassGenericPassword (ixtiyoriy parol), kSecClassInternetPassword (internet xizmatiga parol), kSecClassCertificate (sertifikat), kSecClassKey (kriptografik kalit) va kSecClassIdentity (kalit va sertifikat birikmasi).
Parol saqlanayotganda ilova atributlar bilan lug'at yaratadi: xizmat, hisob, kirish darajasi, belgi. Security framework ma'lumotlarni securityd demoniga uzatadi, u yozuvni qurilmaga bog'langan kalit bilan shifrlaydi va Keychain SQLite-da saqlaydi. Olish xuddi shunday amalga oshiriladi: atributlar bo'yicha so'rov, qidirish, shifrni ochish va ma'lumotlarni qaytarish.
Muhim xususiyat: ilova o'chirilganda iOS avtomatik ravishda ushbu ilova tomonidan yaratilgan Keychain yozuvlarini tozalaydi (iOS 10.3+ dan boshlab). Ilova qayta o'rnatilganda oldingi o'rnatishning Keychain ma'lumotlari, agar iCloud Keychain ishlatilmagan bo'lsa, erishib bo'lmas holga keladi.
import Security
func savePassword(service: String, account: String, password: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecValueData as String: password,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]
SecItemAdd(query as CFDictionary, nil)
}
Keychain beshta asosiy ma'lumot sinfini qo'llab-quvvatlaydi, har biri o'z atributlar to'plami va qo'llanish sohasiga ega. Sinf tanloviga qaysi qidiruv kalitlari mavjudligi va ma'lumotlar qanday shifrlanishi bog'liq.
kSecClassGenericPassword va kSecClassInternetPassword sinflari matnli parollarni saqlash uchun mo'ljallangan. Internet versiyasi qo'shimcha ravishda server ma'lumotlarini saqlaydi: domen, protokol, port va autentifikatsiya yo'li. GenericPassword serverga bog'lanmagan holda istalgan parollarni saqlash uchun ishlatiladi.
Internet parolini saqlashda kSecAttrServer (domen), kSecAttrProtocol (HTTPS, FTP va boshq.), kSecAttrPort va kSecAttrPath ko'rsatilishi mumkin. Bu AutoFill orqali avtomatik to'ldirishda yozuvni aniq identifikatsiya qilish imkonini beradi.
kSecClassKey sinfi simmetrik (AES) va asimmetrik (RSA, EC) kalitlarni saqlaydi. kSecClassCertificate sinfi — X.509 sertifikatlarini. kSecClassIdentity sinfi shaxsiy kalit va tegishli sertifikatni bir yozuvda birlashtiradi.
Asimmetrik kalitlar uchun Keychain atributlarni qo'llab-quvvatlaydi: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (Keychain-da saqlash). Sertifikatlar uchun: kSecAttrLabel (inson o'qiy oladigan nom), kSecAttrSubject (egasining DN), kSecAttrIssuer (beruvchining DN).
| Keychain sinfi | Maqsad | Ma'lumot turi |
|---|---|---|
| kSecClassGenericPassword | Ilova paroli | Data (NSString) |
| kSecClassInternetPassword | Server paroli | Data + server atributlari |
| kSecClassCertificate | X.509 sertifikati | SecCertificate |
| kSecClassKey | Kriptografik kalit | SecKey |
| kSecClassIdentity | Kalit + sertifikat | SecIdentity |
Mahalliy iOS kodida Keychain bilan o'zaro aloqaning asosiy interfeysi — Security framework funksiyalari. Swift va Objective-C uchun qulay funksiyalarga o'ralgan bitta C interfeysi mavjud.
SecItemAdd funksiyasi Keychain-ga yangi element qo'shadi. Kirishda sinf, ma'lumotlar va atributlar bilan lug'at qabul qiladi. errSecSuccess (0) statusi yoki xato kodini qaytaradi. SecItemCopyMatching funksiyasi atributlar bo'yicha qidirishni amalga oshiradi va topilgan ma'lumotlarni qaytaradi.
Qidirish uchun kSecReturnData bayrog'i ishlatiladi — agar true bo'lsa, funksiya yozuv mazmunini qaytaradi. kSecMatchLimit bayrog'i natijalar sonini belgilaydi: kSecMatchLimitOne (bitta) yoki kSecMatchLimitAll (barchasi).
func readPassword(service: String, account: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess else { return nil }
return item as? Data
}
SecItemUpdate mavjud yozuvning atributlari yoki ma'lumotlarini o'zgartirish imkonini beradi. SecItemDelete uzatilgan lug'atga mos keladigan barcha yozuvlarni o'chiradi. O'chirishda tasodifan shared keychain-da boshqalarning yozuvlarini o'chirmaslik uchun yetarli atributlarni ko'rsatish muhimdir.
func deletePassword(service: String, account: String) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account
]
SecItemDelete(query as CFDictionary)
}
Har bir Keychain yozuvi kSecAttrAccessible atributiga ega, bu ma'lumotlar qachon o'qish uchun mavjudligini belgilaydi. Bu xavfsizlik uchun juda muhim: noto'g'ri kirish darajasi ma'lumotlarni himoyasiz qilishi yoki aksincha, kerakli vaqtda erishib bo'lmas qilishi mumkin.
kSecAttrAccessibleWhenUnlocked — ma'lumotlar faqat qurilma qulfi ochilganda mavjud. kSecAttrAccessibleAfterFirstUnlock — qayta yuklashdan keyin birinchi qulf ochilishidan so'ng mavjud. kSecAttrAccessibleAlways — har doim mavjud (tavsiya etilmaydi). ThisDeviceOnly postfiksi ma'lumotlarni zaxira nusxa orqali uzatishni taqiqlaydi.
Secure Enclave ga ega qurilmalarda Keychain shifrlash kaliti qo'shimcha ravishda biometriya bilan himoyalanishi mumkin: kSecAccessControlBiometryCurrentSet yoki kSecAccessControlUserPresence. Bu har bir o'qish operatsiyasi uchun Face ID yoki Touch ID talabini qo'shadi.
iCloud Keychain yozuvlarni Apple qurilmalari o'rtasida end-to-end shifrlash orqali sinxronlashtiradi. Apple shifrni ochilgan ma'lumotlarga kirish huquqiga ega emas. Sinxronizatsiyani yoqish uchun kSecAttrSynchronizable atributini kCFBooleanTrue qiymati bilan qo'shing.
Muhim: sinxronlashtiriladigan yozuvlar ThisDeviceOnly atributiga ega bo'lishi mumkin emas, chunki ular boshqa qurilmalarda mavjud bo'lishi kerak. Barcha qurilmalar yo'qolganda iCloud Keychain tiklash kodi yoki iCloud zaxira kaliti orqali tiklanadi.
Autentifikatsiya tokenlari uchun kSecAttrAccessibleWhenUnlockedThisDeviceOnly dan foydalaning — ma'lumotlar faqat qulfi ochilgan qurilmada mavjud va zaxira nusxaga ko'chirilmaydi. Fon vazifalari uchun mavjud bo'lishi kerak bo'lgan sertifikatlar uchun kSecAttrAccessibleAfterFirstUnlock dan foydalaning. Maxfiy ma'lumotlar uchun hech qachon kSecAttrAccessibleAlways dan foydalanmang.
Sinxronizatsiyani talab qilmaydigan ma'lumotlar uchun har doim ThisDeviceOnly postfiksini qo'shish tavsiya etiladi. Bu sirlarning tasodifan iCloud yoki iTunes backup-ga ko'chirilishining oldini oladi, u erda ular tahlil vositalari bilan olinishi mumkin. Kritik ma'lumotlar uchun mavjudlikni kSecAccessControlUserPresence bilan birlashtiring — bu yozuvni shifrini ochish uchun biometriya yoki kod talabini qo'shadi.
iCloud Keychain dan foydalanganda sinxronlashtiriladigan yozuvlar foydalanuvchining barcha qurilmalarida mavjudligini hisobga oling: agar tajovuzkor bitta qurilmaga kirish imkoniyatiga ega bo'lsa, ma'lumotlar barcha qurilmalarda xavf ostida qolishi mumkin. Izolyatsiya qilingan sirlar uchun ThisDeviceOnly dan foydalaning.
Tez-tez beriladigan savollar
UserDefaults ma'lumotlarni IPA tahlilida mavjud bo'lgan .plist faylida ochiq shaklda saqlaydi. Keychain har bir yozuvni alohida shifrlaydi, apparat shifrlashidan foydalanadi va kirish darajalari, biometriya va iCloud orqali sinxronizatsiyani qo'llab-quvvatlaydi.
iOS simulyatorida har bir ishga tushirishda Keychain tozalanadi. Haqiqiy qurilmada ilovani o'chiring — iOS ushbu dasturchining barcha Keychain yozuvlarini o'chiradi. Tanlab tozalash uchun tegishli atributlar bilan SecItemDelete-ni chaqiring.
Ha, keychain access groups orqali. Ilovalar imzoda bir xil team ID va bir xil keychain-access-groups bilan entitlements-ga ega bo'lishi kerak. Dasturchi Xcode Capabilities-da umumiy kirishni sozlaydi.
Apple qat'iy cheklovni hujjatlashtirmagan, ammo amalda har bir yozuv uchun 1–4 KB dan oshmaslik tavsiya etiladi. Katta hajmlar uchun fayl shifrlash va kalitni Keychain-da saqlash, ma'lumotlarning o'zini esa Documents-da saqlashdan foydalaning.
Jailbreak paytida Keychain himoyasi pasayadi, chunki tajovuzkor root kirishiga ega bo'ladi va Keychain SQLite-ni to'g'ridan-to'g'ri o'qiy oladi. Kritik ma'lumotlar uchun serverdan olingan kalit bilan qo'shimcha shifrlashdan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.