Keychain (Açar zənciri) — iOS-da şifrələr, kriptoqrafik açarlar, sertifikatlar və məxfi qeydlərin təhlükəsiz saxlanması üçün nəzərdə tutulmuş qorunan anbardır. Apple Security Documentation (2025)-ya görə, Keychain A7 çipi və daha yeni olan bütün cihazlarda Secure Enclave vasitəsilə aparat şifrələməsindən istifadə edir. iOS Keychain arxitekturasını başa düşmək hər bir tətbiq inkişaf etdiricisi üçün tokenləri və tətbiq sirlərini düzgün saxlamaq üçün vacibdir.
Başlıca
iOS Keychain — Apple əməliyyat sisteminə daxil edilmiş məxfi məlumatların qorunan saxlama mexanizmidir. UserDefaults və ya adi fayllardan fərqli olaraq, Keychain bütün elementləri aparat səviyyəsində şifrələyir və təhlükəsizlik siyasətlərinə əsaslanan incə giriş nəzarəti təmin edir.
Keychain iOS 2.0-da təqdim edildi və o vaxtdan bəri əhəmiyyətli dəyişikliklərə məruz qaldı: iOS 7-də Secure Enclave vasitəsilə aparat açarları dəstəyi, iOS 9-da Access Groups vasitəsilə tətbiqlər arasında Keychain bölgüsü, iOS 13-də isə LAContext vasitəsilə biometrik bağlama dəstəyi əlavə edildi. Apple WWDC Session (2024) məlumatlarına görə, App Store top 100-dəki iOS tətbiqlərinin 90%-dən çoxu autentifikasiya tokenlərini saxlamaq üçün Keychain-dən istifadə edir.
Arxitektura baxımından Keychain tətbiqin sandboxundan kənarda yerləşən şifrələnmiş SQLite verilənlər bazasıdır. Hər bir element (SecItem) ayrı bir açarla şifrələnir, bu açar isə öz növbəsində Secure Enclave-in aparat açarı tərəfindən qorunur. Sistem xidməti Securityd tətbiqin hüquqlarına (entitlements) və tələb olunan qoruma sinfinə əsaslanaraq Keychain-ə girişi idarə edir.
Keychain-in digər saxlama üsullarına nisbətən mühüm üstünlüyü: məlumatlar avtomatik olaraq ƏS tərəfindən şifrələnir və deşifrələnir. Tətbiq inkişaf etdiricisi kriptoqrafiyanı əllə hüyata keçirməli deyil — sadəcə düzgün parametrlərlə SecItemAdd-i çağırmaq kifayətdir. iOS, Access Groups-un düzgün konfiqurasiyası ilə Keychain-dən olan məlumatların digər tətbiqlər tərəfindən oxuna bilməyəcəyinə zəmanət verir.
Keychain arxitekturası bir neçe səviyyəni əhatə edir: fiziki (Secure Enclave), sistem (Security.framework), tətbiq (API SecItem*) və məntiqi (Access Groups, Protection Classes). Hər səviyyəni başa düşmək sirlərin saxlanmasını düzgün planlaşdırmağa kömək edir.
Keychain ilə işləmək üçün əsas API Security framework funksiyalarıdır: əlavə etmək üçün SecItemAdd, oxumaq üçün SecItemCopyMatching, yeniləmək üçün SecItemUpdate və silmək üçün SecItemDelete. Hər bir funksiya axtarılan və ya saxlanılan elementin atributlarını təsvir edən query lüğəti qəbul edir.
Query-in əsas atributları: kSecClass — element növü (kSecClassGenericPassword, kSecClassKey, kSecClassCertificate), kSecAttrAccount — sinif daxilində unikal identifikator, kSecValueData — saxlanılan məlumatlar (Data), kSecAttrAccessible — qoruma sinfi. SecItemCopyMatching kSecReturnData bayrağı ilə elementin məlumatlarını, kSecMatchLimit ilə isə nəticələrin sayını qaytarır.
Vacibdir: bütün funksiyalar OSStatus statusu qaytarır. Uğurlu əməliyyat errSecSuccess (0) qaytarır. Xətalarlar: errSecItemNotFound (-25300) — element tapılmadı, errSecDuplicateItem (-25299) — element artıq mövcuddur, errSecAuthFailed (-25293) — biometrik autentifikasiya keçilmədi. Tətbiq inkişaf etdiricisi hər bir statusu düzgün idarə etməlidir.
Protection Class — Keychain-dəki məlumatların nə vaxt oxumaq üçün əlçatan olduğunu müyyənləşdirən kSecAttrAccessible atributudur. iOS müxtəlif səviyyəli əlçatanlıq və təhlükəsizliklə altı qoruma sinfini dəstəkləyir.
Əksər ssenarilər üçün tövsiyə olunan sinif kSecAttrAccessibleWhenUnlockedThisDeviceOnly-dir: məlumatlar yalnız cihaz açıq olduqda əlçatandır və iCloud Backup-a kopyalanmır. Yenidən başlatmadan sonra əlçatan olmalı (lakin yalnız ilk açılışdan sonra) məlumatlar üçün kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly istifadə edin. Hər girişdə biometrik autentifikasiya tələb edən kritik məlumatlar üçün kSecAttrAccessibleWhenUnlockedThisDeviceOnly-ni biometriya tələb edən ACL ilə birləşdirin.
ThisDeviceOnly şəkilçisi olmayan siniflər (kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock) iCloud Backup-a kopyalanmağa icazə verir. Bu istifadəçi üçün rahatdır, lakin təhlükəsizliyi azaldır — məlumatlar ehtiyat nüsxədən bərpa edilə bilər. Autentifikasiya tokenləri üçün həmişə ThisDeviceOnly istifadə edin.
Access Control List (ACL) — istifadəçinin autentifikasiyasına əsaslanaraq Keychain elementi ilə əməliyyatları məhdudlaşdıran mexanizmdir. ACL SecAccessControlCreateWithFlags vasitəsilə yaradılır və elementi saxlayarkən kSecAttrAccessControl atributuna ötürülür.
Dəstəklənən bayraqlar: kSecAccessControlUserPresence — istənilən autentifikasiya (Face ID, Touch ID və ya parol kodu), kSecAccessControlBiometryCurrentSet — yalnız biometriya (hazırda qeydiyyatdan keçmiş barmaq izləri və ya üz), kSecAccessControlDevicePasscode — yalnız parol kodu. ACL hər əməliyyata tətbiq edilir: elementin oxunması, yenilənməsi və silinməsi də autentifikasiya tələb edir.
iOS 15+-də kSecAccessControlWatch bayrağı əlavə edildi — Apple Watch üçün, cütləşdirilmiş saat vasitəsilə autentifikasiyaya icazə verir. ACL birləşdirilə bilər: məsələn, kSecAccessControlUserPresence və ya kSecAccessControlBiometryAny seçimli parol kodu ilə (.or oriyentasiyası).
iOS Keychain dörd əsas element sinfini (kSecClass) dəstəkləyir, hər biri öz məlumat növü üçün nəzərdə tutulmuşdur. Sinifin düzgün seçimi elementlərin təşkilini və axtarışını sadələşdirir.
kSecClassGenericPassword — ümumi şifrə: ən çox istifadə edilən sinif. Unikal açarla (kSecAttrAccount) istənilən ikili məlumatları (Data) saxlayır. Tokenlər, API açarları, PIN-kodlar üçün uyğundur. İstifadə üçün əlavə hüquqlar (entitlements) tələb etmir.
kSecClassInternetPassword — internet şifrəsi: şəbək resursu ilə əlaqəli məlumatları saxlayır. Əlavə atributlar: kSecAttrServer (server domeni), kSecAttrProtocol (https, ftp), kSecAttrPort, kSecAttrAuthenticationType. iOS AutoFill vasitəsilə belə şifrələri avtomatik doldura bilər.
kSecClassKey — kriptoqrafik açar: şifrələmə açarlarının (AES, RSA, EC) saxlanması üçün. Açar Data kimi deyil, SecKeyRef kimi saxlanılır. kSecClassCertificate — rəqəmsal sertifikatların saxlanması və yoxlanması üçün X.509 sertifikatı. Hər iki sinif kriptoqrafik əməliyyatların başa düşülməsini və atributların düzgün konfiqurasiyasını tələb edir.
Praktikada mobil tətbiqlərdə Keychain istifadəsinin 95% halları autentifikasiya tokenlərinin saxlanması üçün kSecClassGenericPassword və şəxsi şifrələmə açarlarının saxlanması üçün kSecClassKey ilə əhatə olunur. kSecClassCertificate nadir hallarda istifadə olunur — adətən öz PKI-si olan korporativ tətbiqlərdə.
Keychain ilə Swift-də Security framework-dan istifadə edərək praktiki nümunələri nəzərdən keçirək. Hər bir nümunə xəta idarəetməsi və Protection Class-ın düzgün konfiqurasiyasını ehtiva edir.
Əsas nümunə autentifikasiya tokenini WhenUnlockedThisDeviceOnly qoruması ilə Keychain-də saxlayır. Açar (kSecAttrAccount) xidmət identifikatorudur, məlumatlar (kSecValueData) isə Data formatında 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)
}
Nümunə açarı biometriyaya bağlamaq üçün SecAccessControlCreateWithFlags istifadəsini göstərir. Elementə hər giriş Face ID və ya Touch ID tələb edəcək.
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)
}
}
Nümunə eyni tətbiq inkişaf etdiricisinin tətbiqləri arasında Keychain-ə ümumi giriş üçün Access Group konfiqurasiyasını göstərir. keychain-access-groups entitlement tələb edir.
// Capabilities: Keychain Sharing aktivdir
// 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-dən düzgün istifadə tipik zəifliklərin və məlumat itkisinin qarşısını alan bir neçə əsas qaydaya riayət etməyi tələb edir.
Bütün autentifikasiya sirləri üçün ThisDeviceOnly istifadə edin: kSecAttrAccessibleWhenUnlockedThisDeviceOnly tokenlərin iCloud Backup-a düşməyəcəyinə zəmanət verir. Əgər təcavüzçü ehtiyat nüsxəyə çıxış əldə edərsə, bu bayraqlı Keychain məlumatları əlçatan olmayacaq. İstisna, istifadəçinin bütün cihazlarında əlçatan olmalı məlumatlardır (məsələn, öz xidmətləri üçün şifrələmə açarları), bunlar üçün kSecAttrAccessibleWhenUnlocked-u kSecAttrSynchronizable ilə istifadə edin.
Xam şifrələri saxlamayın — heşləri və ya sessiya tokenlərini saxlayın. Apple Security Guide (2025) istifadəçinin şifrəsinin Keychain-də açıq mətndə saxlanmasını qətiyyənlə tövsiyə etmir. Bunun əvəzinə, OAuth 2.0 vasitəsilə uğurlu autentifikasiyadan sonra serverdən alınan refresh tokeni saxlayın. Şifrə yalnız token əldə etmək üçün istifadə olunur və dərhal yaddaşdan silinir.
Keychain xətalarını düzgün idarə edin: Keychain ilə hər əməliyyat yoxlanılmalı olan OSStatus qaytarır. Xüsusilə diqqət edilməli olanlar: errSecItemNotFound (token müddəti bitib və ya silinib) və errSecAuthFailed (biometriya keçilmədi). Birinci halda tətbiq yeni autentifikasiya tələb etməli, ikincidə — istifadəçiyə alternativ üsul göstərməlidir (parol kodu). Heç vaxt errSecItemNotFound statusuna məhəl qoymayın — bu, nil oxumağa cəhd edərkən tətbiqin çökməsinə səbəb olacaq.
Keychain-i real cihazda test edin: simulatorun Secure Enclave-ı yoxdur və biometrik ACL-ləri dəstəkləmir. Həmişə ssenariləri yoxlayın: ilk işə salma, ehtiyat nüsxədən bərpa, cihaz parolunun dəyişdirilməsi, tətbiqin silinməsi və yenidən quraşdırılması. Real cihazda Keychain tətbiq silindikdən sonra qorunur, ancaq kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly bayrağı istifadə edilməyibsə — bu bayraq parol kodu silindikdə təmizlənir.
Keychain əməliyyatlarının sayını minimuma endirin: hər oxu və ya yazma əməliyyatı axını bloklaya bilən Securityd sistem xidmətinə müraciətdir. Oxunmuş tokenləri sessiya müddətincə yaddaşda keşləyin və Keychain-ə yalnız tətbiq yenidən başladıqda və ya autentifikasiya xətası (serverdən 401) olduqda yenidən müraciət edin. iOS cihaz bağlandıqda Keychain-i avtomatik bloklayır, buna görə də LAContext vasitəsilə biometriya tələbi ilə oxumağı planlaşdırın.
Tez-tez verilən suallar
Bəli, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly və ya kSecAttrAccessibleAfterFirstUnlock qoruma sinifindən istifadə edin. Məlumatlar yenidən başlatmadan sonra cihazın ilk açılışından etibarən əlçatan olacaq. Tətbiq işə salındıqda avtomatik giriş üçün (açılışı gözləmədən) kSecAttrAccessibleAlways istifadə edin, lakin bu təhlükəsizliyi azaldır.
Hər məlumat növü üçün kSecClass ehtiva edən query ilə SecItemDelete-i çağırın. Tətbiqin bütün elementlərini tam təmizləmək üçün bunu edin: SecItemDelete([kSecClass as String: kSecClassGenericPassword] as CFDictionary). kSecClassKey, kSecClassCertificate və kSecClassInternetPassword üçün təkrarlayın.
kSecAttrAccessible məlumatların nə vaxt əlçatan olduğunu müyyənləşdirir (açılışda, ilk açılışdan sonra və s.). kSecAttrAccessControl kimin giriş əldə edə biləcəyini müyyənləşdirir (biometriya, parol kodu, istənilən autentifikasiya). Onlar birləşdirilir: əvvəlcə Protection Class, sonra ACL. Məsələn, məlumatlar yalnız açılışda Və yalnız Face ID-dən sonra əlçatandır.
Səbəblər: element heç vaxt saxlanmayıb, element parol kodu silindikdə təmizlənib (kSecAttrAccessibleWhenPasscodeSet istifadə edilibsə), tətbiq yenidən quraşdırılıb (Keychain qorunur, lakin yeni cihazda ehtiyat nüsxədən bərpa edilmir), Access Group və ya tətbiq inkişaf etdiricisi identifikatoru dəyişib. kSecAttrService və kSecAttrAccount-u yoxlayın.
LocalAuthentication-dan LAContext istifadə edin: context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) çağırın. Əgər true qaytarırsa — cihaz Touch ID və ya Face ID dəstəkləyir. Keychain ACL üçün biometryCurrentSet (yalnız cari biometrik məlumatlar) və ya biometryAny (əvvəllər qeydiyyatdan keçmiş istənilən) bayrağından istifadə edin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun