Keychain (Kalitlar zanjiri) — iOS-da parollar, kriptografik kalitlar, sertifikatlar va maxfiy eslatmalarni xavfsiz saqlash uchun moʻljallangan himoyalangan ombordir. Apple Security Documentation (2025) maʼlumotlariga koʻra, Keychain A7 chipli va undan yangi barcha qurilmalarda Secure Enclave orqali apparat shifrlashdan foydalanadi. iOS Keychain arxitekturasini tushunish har bir dasturchi uchun tokenlar va dastur sirlarini toʻgʻri saqlash uchun zarurdir.
Asosiy
iOS Keychain — Apple operatsion tizimiga oʻrnatilgan maxfiy maʼlumotlarni himoyalangan saqlash mexanizmi. UserDefaults yoki oddiy fayllardan farqli oʻlaroq, Keychain barcha elementlarni apparat darajasida shifrlaydi va xavfsizlik siyosatlariga asoslangan nozik kirish nazoratini taʻminlaydi.
Keychain iOS 2.0 da taqdim etilgan va shundan beri sezilarli oʻzgarishlarga uchradi: iOS 7 da Secure Enclave orqali apparat kalitlari qoʻllab-quvvatlandi, iOS 9 da Access Groups orqali ilovalar oʻrtasida Keychain boʻlimi qoʻshildi, iOS 13 da LAContext orqali biometrik bogʻlash qoʻllab-quvvatlandi. Apple WWDC Session (2024) maʼlumotlariga koʻra, App Store top 100 dagi iOS ilovalarining 90% dan ortigʻi autentifikatsiya tokenlarini saqlash uchun Keychain-dan foydalanadi.
Arxitektura nuqtai nazaridan, Keychain ilova sandboxidan tashqarida joylashgan shifrlangan SQLite maʼlumotlar bazasidir. Har bir element (SecItem) alohida kalit bilan shifrlanadi, bu kalit esa oʻz navbatida Secure Enclave apparat kaliti bilan himoyalanadi. Tizim xizmati Securityd ilovaning huquqlari (entitlements) va soʻralgan himoya sinfiga asoslanib Keychain-ga kirishni boshqaradi.
Keychain-ning boshqa saqlash usullariga nisbatan muhim afzalligi: maʼlumotlar avtomatik ravishda OT tomonidan shifrlanadi va deshifrlanadi. Dasturchi kriptografiyani qoʻlda amalga oshirishi shart emas — toʻgʻri parametrlar bilan SecItemAdd-ni chaqirish kifoya. iOS, Access Groups toʻgʻri sozlanganida, Keychain maʼlumotlarini boshqa ilovalar oʻqiy olmasligini kafolatlaydi.
Keychain arxitekturasi bir necha darajalarni oʻz ichiga oladi: fizik (Secure Enclave), tizim (Security.framework), amaliy (API SecItem*) va mantiqiy (Access Groups, Protection Classes). Har bir darajani tushunish sirlarni saqlashni toʻgʻri loyihalashga yordam beradi.
Keychain bilan ishlash uchun asosiy API Security framework funksiyalaridir: qoʻshish uchun SecItemAdd, oʻqish uchun SecItemCopyMatching, yangilash uchun SecItemUpdate va oʻchirish uchun SecItemDelete. Har bir funksiya qidirilayotgan yoki saqlanayotgan elementning atributlarini tavsiflovchi query lugʻatini qabul qiladi.
Query-ning asosiy atributlari: kSecClass — element turi (kSecClassGenericPassword, kSecClassKey, kSecClassCertificate), kSecAttrAccount — sinf ichidagi noyob identifikator, kSecValueData — saqlanadigan maʼlumotlar (Data), kSecAttrAccessible — himoya sinfi. SecItemCopyMatching kSecReturnData bayrogʻi bilan element maʼlumotlarini, kSecMatchLimit bilan esa natijalar sonini qaytaradi.
Muhim: barcha funksiyalar OSStatus holatini qaytaradi. Muvaffaqiyatli operatsiya errSecSuccess (0) qaytaradi. Xatolar: errSecItemNotFound (-25300) — element topilmadi, errSecDuplicateItem (-25299) — element allaqachon mavjud, errSecAuthFailed (-25293) — biometrik autentifikatsiya muvaffaqiyatsiz tugadi. Dasturchi har bir holatni toʻgʻri boshqarishi kerak.
Protection Class — kSecAttrAccessible atributi boʻlib, Keychain-dagi maʼlumotlar qachon oʻqish uchun mavjudligini aniqlaydi. iOS turli darajadagi mavjudlik va xavfsizlikka ega olti himoya sinfini qoʻllab-quvvatlaydi.
Aksariyat stsenariylar uchun tavsiya etilgan sinf kSecAttrAccessibleWhenUnlockedThisDeviceOnly: maʼlumotlar faqat qurilma qulfi ochiqda mavjud va iCloud Backup-ga nusxalanmaydi. Qayta yuklashdan keyin mavjud boʻlishi kerak boʻlgan (lekin faqat birinchi ochishdan keyin) maʼlumotlar uchun kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly dan foydalaning. Har bir kirishda biometrik autentifikatsiya talab qiladigan muhim maʼlumotlar uchun kSecAttrAccessibleWhenUnlockedThisDeviceOnly-ni biometriya talab qiladigan ACL bilan birlashtiring.
ThisDeviceOnly qoʻshimchasiz sinflar (kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock) iCloud Backup-ga nusxalashga ruxsat beradi. Bu foydalanuvchi uchun qulay, ammo xavfsizlikni pasaytiradi — maʼlumotlar zaxiradan tiklanishi mumkin. Autentifikatsiya tokenlari uchun har doim ThisDeviceOnly dan foydalaning.
Access Control List (ACL) — foydalanuvchi autentifikatsiyasiga asoslanib Keychain elementi bilan operatsiyalarni cheklaydigan mexanizm. ACL SecAccessControlCreateWithFlags orqali yaratiladi va elementni saqlashda kSecAttrAccessControl atributiga uzatiladi.
Qoʻllab-quvvatlanadigan bayroqlar: kSecAccessControlUserPresence — har qanday autentifikatsiya (Face ID, Touch ID yoki parol kodi), kSecAccessControlBiometryCurrentSet — faqat biometriya (hozirda roʻyxatdan oʻtgan barmoq izlari yoki yuz), kSecAccessControlDevicePasscode — faqat parol kodi. ACL har bir operatsiyaga qoʻllaniladi: elementni oʻqish, yangilash va oʻchirish ham autentifikatsiyani talab qiladi.
iOS 15+ da kSecAccessControlWatch bayrogʻi qoʻshildi — Apple Watch uchun, juftlashtirilgan soat orqali autentifikatsiyaga ruxsat beradi. ACL birlashtirilishi mumkin: masalan, kSecAccessControlUserPresence yoki kSecAccessControlBiometryAny ixtiyoriy parol kodi bilan (.or orientatsiyasi).
iOS Keychain toʻrtta asosiy element sinfini (kSecClass) qoʻllab-quvvatlaydi, har biri oʻz maʼlumot turi uchun moʻljallangan. Sinfni toʻgʻri tanlash elementlarni tashkil qilish va qidirishni soddalashtiradi.
kSecClassGenericPassword — umumiy parol: eng koʻp ishlatiladigan sinf. Noyob kalit bilan (kSecAttrAccount) ixtiyoriy ikkilik maʼlumotlarni (Data) saqlaydi. Tokenlar, API kalitlari, PIN-kodlar uchun mos keladi. Foydalanish uchun qoʻshimcha huquqlar (entitlements) talab qilmaydi.
kSecClassInternetPassword — internet paroli: tarmoq resursi bilan bogʼliq maʼlumotlarni saqlaydi. Qoʻshimcha atributlar: kSecAttrServer (server domeni), kSecAttrProtocol (https, ftp), kSecAttrPort, kSecAttrAuthenticationType. iOS AutoFill orqali bunday parollarni avtomatik toʻldirishi mumkin.
kSecClassKey — kriptografik kalit: shifrlash kalitlarini (AES, RSA, EC) saqlash uchun. Kalit Data sifatida emas, SecKeyRef sifatida saqlanadi. kSecClassCertificate — raqamli sertifikatlarni saqlash va tekshirish uchun X.509 sertifikati. Ikkala sinf kriptografik operatsiyalarni tushunishni va atributlarni toʻgʻri sozlashni talab qiladi.
Amalda, mobil ilovalarda Keychain dan foydalanishning %95 hollari autentifikatsiya tokenlarini saqlash uchun kSecClassGenericPassword va shaxsiy shifrlash kalitlarini saqlash uchun kSecClassKey bilan qoplanadi. kSecClassCertificate kamdan-kam qoʻllaniladi — odatda oʻz PKI-ga ega korporativ ilovalarda.
Security framework-dan foydalangan holda Swift-da Keychain bilan ishlashning amaliy misollarini koʻrib chiqamiz. Har bir misol xatolarni boshqarish va Protection Class-ni toʻgʻri sozlashni oʻz ichiga oladi.
Asosiy misol autentifikatsiya tokenini WhenUnlockedThisDeviceOnly himoyasi bilan Keychain-da saqlaydi. Kalit (kSecAttrAccount) xizmat identifikatori, maʼlumotlar (kSecValueData) Data formatidagi tokendir.
import Security
enum KeychainError: Error {
case unexpectedStatus(OSStatus)
}
func saveToken(token: String, service: String) throws {
let data = Data(token.utf8)
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: "auth_token",
kSecValueData as String: data,
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else {
throw KeychainError.unexpectedStatus(status)
}
}
func readToken(service: String) throws -> String {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: "auth_token",
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(
query as CFDictionary, &result
)
guard status == errSecSuccess,
let data = result as? Data else {
throw KeychainError.unexpectedStatus(status)
}
return String(decoding: data, as: UTF8.self)
}
Misol kalitni biometriyaga bogʻlash uchun SecAccessControlCreateWithFlags dan foydalanishni koʻrsatadi. Elementga har bir kirish Face ID yoki Touch ID talab qiladi.
import LocalAuthentication
func saveWithBiometry(data: Data, key: String) throws {
let accessControl = SecAccessControlCreateWithFlags(
nil,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
.biometryCurrentSet,
nil
)
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessControl as String: accessControl as Any
]
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else {
throw KeychainError.unexpectedStatus(status)
}
}
Misol bir dasturchining ilovalari oʻrtasida Keychain-ga umumiy kirish uchun Access Group sozlashni koʻrsatadi. keychain-access-groups entitlement talab qiladi.
// Capabilities: Keychain Sharing yoqilgan
// App IDs: group.com.example.shared
func saveSharedToken(token: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "shared_token",
kSecValueData as String: token,
kSecAttrAccessGroup as String:
"group.com.example.shared",
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemAdd(query as CFDictionary, nil)
}
iOS Keychain dan toʻgʻri foydalanish odatdagi zaifliklar va maʼlumot yoʻqotilishining oldini oladigan bir necha asosiy qoidalarga rioya qilishni talab qiladi.
Barcha autentifikatsiya sirlari uchun ThisDeviceOnly dan foydalaning: kSecAttrAccessibleWhenUnlockedThisDeviceOnly tokenlarning iCloud Backup-ga tushmasligini kafolatlaydi. Agar tajovuzkor zaxiraga kirish imkoniyatiga ega boʻlsa, bu bayroqli Keychain maʼlumotlari mavjud boʻlmaydi. Istisno — foydalanuvchining barcha qurilmalarida mavjud boʻlishi kerak boʻlgan maʼlumotlar (masalan, oʻz xizmatlari uchun shifrlash kalitlari), ular uchun kSecAttrAccessibleWhenUnlocked-ni kSecAttrSynchronizable bilan ishlating.
Xom parollarni saqlamang — heshlar yoki sessiya tokenlarini saqlang. Apple Security Guide (2025) foydalanuvchi parolini Keychain-da ochiq matnda saqlashni hech qachon tavsiya etmaydi. Buning oʻrniga, OAuth 2.0 orqali muvaffaqiyatli autentifikatsiyadan keyin serverdan olingan refresh token-ni saqlang. Parol faqat tokenni olish uchun ishlatiladi va darhol xotiradan oʻchiriladi.
Keychain xatolarini toʻgʻri boshqaring: Keychain bilan har bir operatsiya tekshirilishi kerak boʻlgan OSStatus qaytaradi. Ayniqsa eʻtibor bering: errSecItemNotFound (token muddati tugagan yoki oʻchirilgan) va errSecAuthFailed (biometriya muvaffaqiyatsiz). Birinchi holatda ilova yangi autentifikatsiyani soʻrashi kerak, ikkinchisida — foydalanuvchiga muqobil usulni koʻrsatishi kerak (parol kodi). Hech qachon errSecItemNotFound holatini eʻtiborsiz qoldirmang — bu nil ni oʻqishga urinishda ilovaning ishdan chiqishiga olib keladi.
Keychain-ni haqiqiy qurilmada sinab koʻring: simulyatorda Secure Enclave yoʻq va biometrik ACL-larni qoʻllab-quvvatlamaydi. Har doim stsenariylarni tekshiring: birinchi ishga tushirish, zaxiradan tiklash, qurilma parolini oʻzgartirish, ilovani oʻchirish va qayta oʻrnatish. Haqiqiy qurilmada Keychain ilova oʻchirilgandan keyin saqlanadi, faqat kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly bayrogʻi ishlatilmagan boʻlsa — bu bayroq parol kodi olib tashlanganda tozalanadi.
Keychain operatsiyalari sonini minimallashtiring: har bir oʻqish yoki yozish operatsiyasi oqimni bloklashi mumkin boʻlgan Securityd tizim xizmatiga murojaatdir. Oʻqilgan tokenlarni sessiya davomida xotirada keshlang va Keychain-ga faqat ilova qayta ishga tushirilganda yoki autentifikatsiya xatosi (serverdan 401) boʻlganda qayta murojaat qiling. iOS qurilma qulflanganda Keychain-ni avtomatik bloklaydi, shuning uchun LAContext orqali biometriya soʻrovi bilan oʻqishni rejalashtiring.
Koʻp beriladigan savollar
Ha, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly yoki kSecAttrAccessibleAfterFirstUnlock himoya sinfidan foydalaning. Maʼlumotlar qayta yuklashdan keyin qurilmaning birinchi ochilishidan soʻng mavjud boʻladi. Ilova ishga tushirilganda avtomatik kirish uchun (ochishni kutmasdan) kSecAttrAccessibleAlways dan foydalaning, ammo bu xavfsizlikni pasaytiradi.
Har bir maʼlumot turi uchun kSecClass ni oʻz ichiga olgan query bilan SecItemDelete-ni chaqiring. Ilovaning barcha elementlarini toʻliq tozalash uchun: SecItemDelete([kSecClass as String: kSecClassGenericPassword] as CFDictionary). kSecClassKey, kSecClassCertificate va kSecClassInternetPassword uchun takrorlang.
kSecAttrAccessible maʼlumotlar qachon mavjudligini aniqlaydi (ochishda, birinchi ochishdan keyin va h.k.). kSecAttrAccessControl kim kirishi mumkinligini aniqlaydi (biometriya, parol kodi, har qanday autentifikatsiya). Ular birlashtiriladi: avval Protection Class, keyin ACL. Masalan, maʼlumotlar faqat ochishda VA faqat Face ID dan keyin mavjud.
Sabablar: element hech qachon saqlanmagan, element parol kodi olib tashlanganda tozalangan (kSecAttrAccessibleWhenPasscodeSet ishlatilgan boʻlsa), ilova qayta oʻrnatilgan (Keychain saqlanadi, lekin yangi qurilmada zaxiradan tiklanmaydi), Access Group yoki dasturchi jamoasi identifikatori oʻzgargan. kSecAttrService va kSecAttrAccount-ni tekshiring.
LocalAuthentication-dan LAContext dan foydalaning: context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ni chaqiring. Agar true qaytarsa — qurilma Touch ID yoki Face ID ni qoʻllab-quvvatlaydi. Keychain ACL uchun biometryCurrentSet (faqat joriy biometrik maʼlumotlar) yoki biometryAny (avval roʻyxatdan oʻtgan har qanday) bayrogʻidan 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.