Middle
Որտե՞ղ կպահեիք օգտվողի պաշտպանված տվյալները:
sobes.tech AI
Պատասխան AI-ից
ԻՕՍ-ի վրա օգտագործվող պաշտպանված տվյալների պահպանման համար ես կօգտագործեի հետևյալ վայրերը՝ տվյալների տեսակից և անվտանգության մակարդակից կախված:
-
Keychain Services:
- Հարմար է փոքր ծավալի գաղտնի տեղեկատվության պահպանման համար, ինչպիսիք են գաղտնաբառերը, թույլտվության նշանները, կոդավորող բանալիները:
- Սիստեմային դեմոն
securitydկառավարում է keychain-ը և պահում տվյալները կոդավորված տեսքով՝ սկավառակի վրա: - Աջակցում է տարբեր հասանելիության մակարդակների (օրինակ՝ հասանելի միայն սարքի ապակոդավորելու ժամանակ):
- Տվյալները ավտոմատ սինխրոնիզացվում են iCloud Keychain-ի միջոցով, եթե ակտիվացված է:
import Foundation import Security func savePassword(service: String, account: String, password: String) -> OSStatus { let data = password.data(using: .utf8)! let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecValueData as String: data ] SecItemDelete(query as CFDictionary) // Գնահատում է գոյություն ունեցող գրառումը return SecItemAdd(query as CFDictionary, nil) // Ավելացնում է նոր գրառում } -
Encrypted Core Data / Realm:
- Հարմար է կառուցվածքային տվյալների պահպանման համար, որոնք պահանջում են բազայի մակարդակով կոդավորում:
- Core Data-ն աջակցում է երրորդ կողմի ընդարձակումներին՝ կոդավորման համար (օրինակ՝ RNCryptor):
- Realm Database-ն ունի ներքին ֆայլի կոդավորման հնարավորություն:
- Կոդավորման բանալին պետք է պահվի Keychain-ում:
// Realm-ի կոդավորման օրինակ import RealmSwift func setupEncryptedRealm() throws { var config = Realm.Configuration() if let key = KeychainHelper.getRealmEncryptionKey() { // Բացառում է բանալին Keychain-ից config.encryptionKey = key } else { // Գեներացնում է նոր բանալին, պահում է Keychain-ում և օգտագործում let newKey = NSMutableData(length: 64)! _ = SecRandomCopyBytes(kSecRandomDefault, newKey.length, newKey.mutableBytes) KeychainHelper.saveRealmEncryptionKey(key: newKey as Data) config.encryptionKey = newKey as Data } let realm = try Realm(configuration: config) // Օգտագործում է Realm-ը } -
File Protection APIs:
- Ֆայլերի կոդավորման համար, որոնք պահվում են հավելվածի ֆայլային համակարգում:
- iOS-ը ավտոմատ կոդավորում է ֆայլերը ֆայլային համակարգի մակարդակով՝ Secure Enclave-ի կառավարող բանալիներով:
- Կարող եք սահմանել տարբեր պաշտպանության ռեժիմներ (օրինակ՝
complete,completeUnlessOpen,completeUntilFirstUserAuthentication,none)՝ սարքի բլոկավորման վիճակի վրա հիմնված մուտքի վերահսկման համար:
func saveProtectedDataToFile(data: Data, fileName: String) throws { let fileManager = FileManager.default let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask) guard let documentDirectory = urls.first else { throw NSError(domain: "MyApp", code: 1, userInfo: [NSLocalizedDescriptionKey: "Document directory not found"]) } let fileURL = documentDirectory.appendingPathComponent(fileName) // Սահմանում է պաշտպանության ռեժիմ let options: Data.WritingOptions = .atomicWrite let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Օրինակ՝ իրական պաշտպանական տարբերակները սահմանվում են ֆայլի հատկություններով կամ info.plist-ում try data.write(to: fileURL, options: options) // Ֆայլային համակարգի պաշտպանության հատկությունների սահմանում (օրինակ) var attributes: [FileAttributeKey : Any] = [:] attributes[.protectionKey] = FileProtectionType.complete try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path) } -
Secure Enclave:
- Հատուկ հագեցած պրոցեսոր՝ առանձին հիմնական պրոցեսորից, որը նախատեսված է կրիպտոգրաֆիկ բանալիների և տվյալների պահպանման և մշակման համար:
- Օգտագործվում է Touch ID / Face ID և այլ զգայուն գործողությունների համար:
- Բանալիները, որոնք պահվում են Secure Enclave-ում, երբեք չեն հեռանում նրանից և չեն հասանելի հիմնական պրոցեսորին կամ օպերացիոն համակարգին:
- Հարմար է բանալիների սերունդ, պահպանում և օգտագործում՝ ստորագրության կամ կոդավորման համար, որտեղ կարևոր է պաշտպանությունը ծրագրային հարձակումներից:
import CryptoKit import LocalAuthentication func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey { let accessControl = SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Հասանելի է կոդի սահմանման դեպքում [.userPresence], // Պահանջվում է օգտվողի նույնականացում (Touch ID/Face ID) nil )! let attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, // Բանալին մշտական կլինի kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Անվտանգ նշան kSecAttrAccessControl as String: accessControl ] ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } // Կարող եք ստանալ բանալիները Secure Enclave-ից նշանագրման կամ կոդավորման համար՝ նշանագրման տվյալների փոխարկումից հետո return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Օրինակ՝ փոխարկում SecKey-ից Data-ին }
Ընտրությունը կախված է՝
- Տվյալների չափից (փոքր ծավալ՝ vs կառուցվածքային տվյալներ)
- Տվյալների տեսակից (գաղտնաբառ՝ vs ֆայլ՝ vs կրիպտոգրաֆիկ բանալին)
- Պաշտպանության մակարդակից
- Սինխրոնիզացիայի անհրաժեշտությունից սարքերի միջև (Keychain)
- Օգտագործողի նույնականացման անհրաժեշտությունից (Secure Enclave, File Protection)