Keychain হলো iOS-এ একটি সুরক্ষিত স্টোরেজ যা পাসওয়ার্ড, ক্রিপ্টোগ্রাফিক কী, সার্টিফিকেট এবং গোপনীয় নোট নিরাপদে সংরক্ষণ করার জন্য ডিজাইন করা হয়েছে। Apple Security Documentation (2025) অনুসারে, Keychain A7 চিপ এবং তার নতুন ডিভাইসগুলিতে Secure Enclave-এর মাধ্যমে হার্ডওয়্যার এনক্রিপশন ব্যবহার করে। iOS Keychain-এর আর্কিটেকচার বোঝা প্রতিটি ডেভেলপারের জন্য অ্যাপ্লিকেশন টোকেন এবং সিক্রেট সঠিকভাবে সংরক্ষণ করার জন্য অপরিহার্য।
মূল বিষয়
iOS Keychain হলো Apple-এর অপারেটিং সিস্টেমে নির্মিত গোপনীয় ডেটা সংরক্ষণের একটি সুরক্ষিত ব্যবস্থা। UserDefaults বা সাধারণ ফাইলের বিপরীতে, Keychain সমস্ত আইটেমকে হার্ডওয়্যার স্তরে এনক্রিপ্ট করে এবং সুরক্ষা নীতির উপর ভিত্তি করে সূক্ষ্ম অ্যাক্সেস নিয়ন্ত্রণ প্রদান করে।
Keychain iOS 2.0-এ চালু হয়েছিল এবং তারপর থেকে উল্লেখযোগ্য পরিবর্তন হয়েছে: iOS 7-এ Secure Enclave-এর মাধ্যমে হার্ডওয়্যার কী সমর্থন যুক্ত হয়, iOS 9-এ Access Groups-এর মাধ্যমে অ্যাপগুলির মধ্যে Keychain শেয়ারিং চালু হয়, iOS 13-এ LAContext-এর মাধ্যমে বায়োমেট্রিক বাইন্ডিং সমর্থন যুক্ত হয়। Apple WWDC Session (2024) অনুসারে, App Store-এর শীর্ষ 100-এ 90% এর বেশি iOS অ্যাপ প্রমাণীকরণ টোকেন সংরক্ষণের জন্য Keychain ব্যবহার করে।
স্থাপত্যিকভাবে, Keychain অ্যাপ্লিকেশন স্যান্ডবক্সের বাইরে অবস্থিত একটি এনক্রিপ্টেড SQLite ডেটাবেস। প্রতিটি আইটেম (SecItem) একটি পৃথক কী দিয়ে এনক্রিপ্ট করা হয়, যা পরিবর্তে Secure Enclave হার্ডওয়্যার কী দ্বারা সুরক্ষিত। সিস্টেম সার্ভিস Securityd অ্যাপ্লিকেশন এনটাইটেলমেন্ট এবং অনুরোধকৃত সুরক্ষা শ্রেণির উপর ভিত্তি করে Keychain-এ অ্যাক্সেস পরিচালনা করে।
অন্যান্য স্টোরেজ পদ্ধতির তুলনায় Keychain-এর একটি গুরুত্বপূর্ণ সুবিধা: ডেটা OS দ্বারা স্বয়ংক্রিয়ভাবে এনক্রিপ্ট এবং ডিক্রিপ্ট হয়। ডেভেলপারকে ম্যানুয়ালি ক্রিপ্টোগ্রাফি বাস্তবায়নের প্রয়োজন নেই - শুধু সঠিক প্যারামিটার সহ SecItemAdd কল করুন। iOS গ্যারান্টি দেয় যে Keychain থেকে ডেটা অন্যান্য অ্যাপ্লিকেশন পড়তে পারে না (যখন Access Groups সঠিকভাবে কনফিগার করা থাকে)।
Keychain আর্কিটেকচারে বেশ কয়েকটি স্তর অন্তর্ভুক্ত রয়েছে: শারীরিক (Secure Enclave), সিস্টেম (Security.framework), অ্যাপ্লিকেশন (SecItem* API) এবং লজিক্যাল (Access Groups, Protection Classes)। প্রতিটি স্তর বোঝা সিক্রেট স্টোরেজ সঠিকভাবে ডিজাইন করতে সহায়তা করে।
Keychain নিয়ে কাজ করার জন্য প্রধান API হলো Security framework-এর ফাংশন: SecItemAdd যোগ করার জন্য, SecItemCopyMatching পড়ার জন্য, SecItemUpdate আপডেট করার জন্য এবং SecItemDelete মুছে ফেলার জন্য। প্রতিটি ফাংশন একটি query অভিধান নেয় যা অনুসন্ধান বা সংরক্ষণ করার আইটেমের বৈশিষ্ট্য বর্ণনা করে।
মূল query বৈশিষ্ট্য: kSecClass - আইটেমের ধরন (kSecClassGenericPassword, kSecClassKey, kSecClassCertificate), kSecAttrAccount - শ্রেণির মধ্যে অনন্য শনাক্তকারী, kSecValueData - সংরক্ষিত ডেটা (Data), kSecAttrAccessible - সুরক্ষা শ্রেণি। SecItemCopyMatching kSecReturnData ফ্ল্যাগ সহ আইটেম ডেটা ফেরত দেয়, kSecMatchLimit সহ - ফলাফলের সংখ্যা।
গুরুত্বপূর্ণ: সমস্ত ফাংশন একটি OSStatus ফেরত দেয়। সফল অপারেশন errSecSuccess (0) ফেরত দেয়। ত্রুটি: errSecItemNotFound (-25300) - আইটেম পাওয়া যায়নি, errSecDuplicateItem (-25299) - আইটেম ইতিমধ্যে বিদ্যমান, errSecAuthFailed (-25293) - বায়োমেট্রিক প্রমাণীকরণ ব্যর্থ। ডেভেলপারকে প্রতিটি অবস্থা সঠিকভাবে পরিচালনা করতে হবে।
Protection Class হলো kSecAttrAccessible বৈশিষ্ট্য যা নির্ধারণ করে কখন Keychain-এ ডেটা পড়ার জন্য উপলব্ধ। iOS বিভিন্ন স্তরের উপলব্ধতা এবং সুরক্ষা সহ ছয়টি সুরক্ষা শ্রেণি সমর্থন করে।
বেশিরভাগ পরিস্থিতির জন্য প্রস্তাবিত শ্রেণি হলো kSecAttrAccessibleWhenUnlockedThisDeviceOnly: ডেটা কেবল তখনই উপলব্ধ যখন ডিভাইস আনলক থাকে এবং iCloud Backup-এ কপি হয় না। রিবুটের পরে উপলব্ধ ডেটার জন্য (কিন্তু শুধুমাত্র প্রথম আনলকের পরে), kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly ব্যবহার করুন। গুরুত্বপূর্ণ ডেটার জন্য যার প্রতিটি অ্যাক্সেসে বায়োমেট্রিক প্রমাণীকরণ প্রয়োজন, kSecAttrAccessibleWhenUnlockedThisDeviceOnly-কে বায়োমেট্রি প্রয়োজন এমন ACL-এর সাথে একত্রিত করুন।
ThisDeviceOnly প্রত্যয় ছাড়া শ্রেণিগুলি (kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock) iCloud Backup-এ কপি করার অনুমতি দেয়। এটি ব্যবহারকারীর জন্য সুবিধাজনক কিন্তু সুরক্ষা হ্রাস করে - ব্যাকআপ থেকে ডেটা পুনরুদ্ধার করা যেতে পারে। প্রমাণীকরণ টোকেনের জন্য, সর্বদা ThisDeviceOnly ব্যবহার করুন।
Access Control List (ACL) একটি পদ্ধতি যা ব্যবহারকারী প্রমাণীকরণের উপর ভিত্তি করে Keychain আইটেমে অপারেশন সীমাবদ্ধ করে। ACL SecAccessControlCreateWithFlags-এর মাধ্যমে সেট করা হয় এবং আইটেম সংরক্ষণ করার সময় kSecAttrAccessControl বৈশিষ্ট্যে পাস করা হয়।
সমর্থিত ফ্ল্যাগ: kSecAccessControlUserPresence - যেকোনো প্রমাণীকরণ (Face ID, Touch ID, বা পাসকোড), kSecAccessControlBiometryCurrentSet - শুধুমাত্র বায়োমেট্রি (বর্তমানে নিবন্ধিত আঙুলের ছাপ বা মুখ), kSecAccessControlDevicePasscode - শুধুমাত্র পাসকোড। ACL প্রতিটি অপারেশনে প্রযোজ্য: আইটেম পড়া, আপডেট করা এবং মুছে ফেলার জন্যও প্রমাণীকরণ প্রয়োজন।
iOS 15+ এ ফ্ল্যাগ kSecAccessControlWatch আবির্ভূত হয়েছে - Apple Watch-এর জন্য, যা পেয়ার করা ঘড়ির মাধ্যমে প্রমাণীকরণের অনুমতি দেয়। ACL একত্রিত করা যেতে পারে: উদাহরণস্বরূপ, kSecAccessControlUserPresence বা kSecAccessControlBiometryAny ঐচ্ছিক পাসকোড (.or ওরিয়েন্টেশন) সহ।
iOS Keychain চারটি প্রধান আইটেম শ্রেণি (kSecClass) সমর্থন করে, প্রতিটি নিজস্ব ডেটার ধরণের জন্য ডিজাইন করা হয়েছে। সঠিক শ্রেণি নির্বাচন করা সংগঠন এবং আইটেম অনুসন্ধানকে সহজ করে।
kSecClassGenericPassword - জেনেরিক পাসওয়ার্ড: সবচেয়ে বেশি ব্যবহৃত শ্রেণি। একটি অনন্য কী (kSecAttrAccount) সহ নির্বিচারে বাইনারি ডেটা (Data) সংরক্ষণ করে। টোকেন, API কী, PIN কোডের জন্য উপযুক্ত। ব্যবহারের জন্য অতিরিক্ত এনটাইটেলমেন্টের প্রয়োজন নেই।
kSecClassInternetPassword - ইন্টারনেট পাসওয়ার্ড: নেটওয়ার্ক সম্পদের সাথে যুক্ত ডেটা সংরক্ষণ করে। অতিরিক্ত বৈশিষ্ট্য: kSecAttrServer (সার্ভার ডোমেন), kSecAttrProtocol (https, ftp), kSecAttrPort, kSecAttrAuthenticationType। iOS AutoFill-এর মাধ্যমে এই ধরনের পাসওয়ার্ড স্বয়ংক্রিয়ভাবে পূরণ করতে পারে।
kSecClassKey - ক্রিপ্টোগ্রাফিক কী: এনক্রিপশন কী (AES, RSA, EC) সংরক্ষণের জন্য। কী SecKeyRef হিসাবে সংরক্ষণ করা হয়, Data হিসাবে নয়। kSecClassCertificate - ডিজিটাল সার্টিফিকেট সংরক্ষণ এবং যাচাই করার জন্য X.509 সার্টিফিকেট। উভয় শ্রেণির জন্য ক্রিপ্টোগ্রাফিক অপারেশন এবং সঠিক বৈশিষ্ট্য কনফিগারেশন বোঝার প্রয়োজন।
বাস্তবে, মোবাইল অ্যাপে Keychain-এর 95% ব্যবহার প্রমাণীকরণ টোকেন সংরক্ষণের জন্য kSecClassGenericPassword এবং ব্যক্তিগত এনক্রিপশন কী সংরক্ষণের জন্য kSecClassKey দ্বারা আচ্ছাদিত। kSecClassCertificate খুব কমই ব্যবহৃত হয় - সাধারণত নিজস্ব PKI সহ এন্টারপ্রাইজ অ্যাপে।
আসুন Security framework ব্যবহার করে Swift-এ Keychain নিয়ে কাজ করার ব্যবহারিক উদাহরণ দেখি। প্রতিটি উদাহরণে ত্রুটি পরিচালনা এবং সঠিক Protection Class কনফিগারেশন অন্তর্ভুক্ত রয়েছে।
একটি মৌলিক উদাহরণ WhenUnlockedThisDeviceOnly সুরক্ষা সহ Keychain-এ একটি প্রমাণীকরণ টোকেন সংরক্ষণ করে। কী (kSecAttrAccount) হলো সার্ভিস শনাক্তকারী, ডেটা (kSecValueData) হলো Data বিন্যাসে টোকেন।
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)
}
উদাহরণটি একটি কীকে বায়োমেট্রির সাথে বাঁধতে SecAccessControlCreateWithFlags ব্যবহার প্রদর্শন করে। আইটেমটিতে প্রতিটি অ্যাক্সেসের জন্য Face ID বা Touch ID প্রয়োজন হবে।
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)
}
}
উদাহরণটি একই ডেভেলপারের অ্যাপগুলির মধ্যে শেয়ার করা Keychain অ্যাক্সেসের জন্য Access Group কনফিগার করা দেখায়। keychain-access-groups এনটাইটেলমেন্ট প্রয়োজন।
// Capabilities: Keychain Sharing সক্ষম
// 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-এর সঠিক ব্যবহার বেশ কয়েকটি মূল নিয়ম অনুসরণ করা প্রয়োজন যা সাধারণ দুর্বলতা এবং ডেটা ক্ষতি প্রতিরোধ করে।
সমস্ত প্রমাণীকরণ সিক্রেটের জন্য ThisDeviceOnly ব্যবহার করুন: kSecAttrAccessibleWhenUnlockedThisDeviceOnly নিশ্চিত করে যে টোকেন iCloud Backup-এ না যায়। যদি একজন আক্রমণকারী ব্যাকআপে অ্যাক্সেস পায়, তাহলে এই ফ্ল্যাগযুক্ত Keychain ডেটা উপলব্ধ হবে না। ব্যতিক্রম হলো ডেটা যা ব্যবহারকারীর সমস্ত ডিভাইসে উপলব্ধ হওয়া উচিত (যেমন, মালিকানাধীন পরিষেবাগুলির জন্য এনক্রিপশন কী), যার জন্য kSecAttrAccessibleWhenUnlocked kSecAttrSynchronizable-এর সাথে ব্যবহার করুন।
কাঁচা পাসওয়ার্ড সংরক্ষণ করবেন না - হ্যাশ বা সেশন টোকেন সংরক্ষণ করুন। Apple Security Guide (2025) Keychain-এ ব্যবহারকারীর পাসওয়ার্ড প্লেইন টেক্সটে কখনো সংরক্ষণ না করার সুপারিশ করে। পরিবর্তে, OAuth 2.0-এর মাধ্যমে সফল প্রমাণীকরণের পরে সার্ভার থেকে প্রাপ্ত রিফ্রেশ টোকেন সংরক্ষণ করুন। পাসওয়ার্ড শুধুমাত্র টোকেন পাওয়ার জন্য ব্যবহৃত হয় এবং অবিলম্বে মেমরি থেকে মুছে ফেলা হয়।
Keychain ত্রুটিগুলি সঠিকভাবে পরিচালনা করুন: প্রতিটি Keychain অপারেশন একটি OSStatus ফেরত দেয় যা পরীক্ষা করতে হবে। errSecItemNotFound (টোকেন মেয়াদোত্তীর্ণ বা মুছে ফেলা) এবং errSecAuthFailed (বায়োমেট্রি ব্যর্থ) এর দিকে বিশেষ মনোযোগ দিন। প্রথম ক্ষেত্রে, অ্যাপটির নতুন প্রমাণীকরণ অনুরোধ করা উচিত; দ্বিতীয় ক্ষেত্রে, ব্যবহারকারীকে একটি বিকল্প পদ্ধতি (পাসকোড) দেখান। কখনই errSecItemNotFound অবস্থা উপেক্ষা করবেন না - এটি nil পড়ার চেষ্টা করলে অ্যাপ ক্র্যাশ করবে।
Keychain একটি বাস্তব ডিভাইসে পরীক্ষা করুন: সিমুলেটরে Secure Enclave নেই এবং বায়োমেট্রিক ACL সমর্থন করে না। সর্বদা পরিস্থিতি পরীক্ষা করুন: প্রথম লঞ্চ, ব্যাকআপ থেকে পুনরুদ্ধার, ডিভাইস পাসওয়ার্ড পরিবর্তন, অ্যাপ মুছে ফেলা এবং পুনরায় ইনস্টল করা। বাস্তব ডিভাইসে, অ্যাপ মুছে ফেলার সময় Keychain টিকে থাকে, কিন্তু শুধুমাত্র যদি kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly ফ্ল্যাগ ব্যবহার না করা হয়, যা পাসকোড সরানোর সময় মুছে যায়।
Keychain অপারেশনের সংখ্যা কমিয়ে আনুন: প্রতিটি পড়া বা লেখার অপারেশন সিস্টেম সার্ভিস Securityd-এ কল, যা থ্রেড ব্লক করতে পারে। সেশনের সময়কালের জন্য পড়া টোকেন মেমরিতে ক্যাশ করুন এবং শুধুমাত্র অ্যাপ পুনরায় চালু করার সময় বা প্রমাণীকরণ ত্রুটিতে (সার্ভার থেকে 401) আবার Keychain অ্যাক্সেস করুন। iOS ডিভাইস লক হলে স্বয়ংক্রিয়ভাবে Keychain লক করে, তাই বায়োমেট্রিক অনুরোধ সহ LAContext-এর মাধ্যমে পড়ার পরিকল্পনা করুন।
সচরাচর জিজ্ঞাসা
হ্যাঁ, সুরক্ষা শ্রেণি kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly বা kSecAttrAccessibleAfterFirstUnlock ব্যবহার করুন। রিবুটের পরে প্রথম ডিভাইস আনলকের পরে ডেটা উপলব্ধ হবে। অ্যাপ লঞ্চে স্বয়ংক্রিয় অ্যাক্সেসের জন্য (আনলকের জন্য অপেক্ষা না করে), kSecAttrAccessibleAlways ব্যবহার করুন, কিন্তু এটি সুরক্ষা হ্রাস করে।
প্রতিটি ডেটার ধরণের জন্য kSecClass সম্বলিত query সহ SecItemDelete কল করুন। সমস্ত অ্যাপ আইটেম সম্পূর্ণ পরিষ্কার করার জন্য,実行 করুন: SecItemDelete([kSecClass as String: kSecClassGenericPassword] as CFDictionary)। kSecClassKey, kSecClassCertificate এবং kSecClassInternetPassword-এর জন্য পুনরাবৃত্তি করুন।
kSecAttrAccessible নির্ধারণ করে কখন ডেটা উপলব্ধ (আনলকে, প্রথম আনলকের পরে, ইত্যাদি)। kSecAttrAccessControl নির্ধারণ করে কে অ্যাক্সেস করতে পারে (বায়োমেট্রি, পাসকোড, যেকোনো প্রমাণীকরণ)। এগুলি একত্রিত হয়: প্রথমে Protection Class, তারপর ACL। উদাহরণস্বরূপ, ডেটা শুধুমাত্র আনলকে এবং শুধুমাত্র Face ID-এর পরে উপলব্ধ।
কারণ: আইটেমটি কখনও সংরক্ষণ করা হয়নি, পাসকোড সরানোর সময় আইটেমটি মুছে ফেলা হয়েছে (যদি kSecAttrAccessibleWhenPasscodeSet ব্যবহার করা হয়), অ্যাপ পুনরায় ইনস্টল করা হয়েছে (Keychain টিকে থাকে কিন্তু নতুন ডিভাইসে ব্যাকআপ থেকে পুনরুদ্ধার হয় না), Access Group বা ডেভেলপার টিম শনাক্তকারী পরিবর্তিত হয়েছে। kSecAttrService এবং kSecAttrAccount পরীক্ষা করুন।
LocalAuthentication থেকে LAContext ব্যবহার করুন: context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) কল করুন। যদি true ফেরত দেয় - ডিভাইসটি Touch ID বা Face ID সমর্থন করে। Keychain ACL-এর জন্য, biometryCurrentSet ফ্ল্যাগ (শুধুমাত্র বর্তমান বায়োমেট্রিক ডেটা) বা biometryAny (পূর্বে নিবন্ধিত যেকোনো) ব্যবহার করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন