Secure Storage iOS in Swift

Kalidoss Shanmugam
4 min readJul 31, 2024

--

When it comes to storing sensitive data securely on iOS, the Keychain is the go-to option for many developers. However, there are several alternatives that can offer additional features or simplified APIs. Here, we explore the top 10 Keychain security storage alternatives for iOS in Swift, including code samples, advantages, and disadvantages.

Table of Contents

  1. SwiftKeychainWrapper
  2. SAMKeychain
  3. Lockbox
  4. Valet
  5. SecureEnclave
  6. BiometricAuthentication
  7. Data Protection API
  8. Realm
  9. SQLite with Encryption
  10. CloudKit

1. SwiftKeychainWrapper

Overview: SwiftKeychainWrapper is a simple wrapper for the iOS Keychain, providing an easy-to-use interface for storing and retrieving data.

Code Sample:

import SwiftKeychainWrapper

// Saving data
KeychainWrapper.standard.set("super_secret_password", forKey: "userPassword")
// Retrieving data
if let password = KeychainWrapper.standard.string(forKey: "userPassword") {
print("Retrieved password: \(password)")
}

Advantages:

  • Simplified API
  • Secure storage
  • Widely used and maintained

Disadvantages:

  • Dependency on a third-party library

2. SAMKeychain

Overview: SAMKeychain provides a simple API for interacting with the Keychain, suitable for storing passwords and other sensitive data.

Code Sample:

import SAMKeychain

// Saving data
SAMKeychain.setPassword("super_secret_password", forService: "com.example.myapp", account: "userAccount")

// Retrieving data
if let password = SAMKeychain.password(forService: "com.example.myapp", account: "userAccount") {
print("Retrieved password: \(password)")
}

Advantages:

  • Simplified API
  • Secure storage
  • Supports access groups

Disadvantages:

  • Dependency on a third-party library

3. Lockbox

Overview: Lockbox offers an easy-to-use interface for securely storing key-value pairs in the Keychain.

Code Sample:

import Lockbox

// Saving data
Lockbox.setString("super_secret_password", forKey: "userPassword")

// Retrieving data
if let password = Lockbox.string(forKey: "userPassword") {
print("Retrieved password: \(password)")
}

Advantages:

  • Simplified API
  • Secure storage
  • Easy integration

Disadvantages:

  • Dependency on a third-party library

4. Valet

Overview: Valet is a secure data storage library for iOS, macOS, tvOS, and watchOS that uses the Keychain internally.

Code Sample:

import Valet

let myValet = Valet.valet(with: Identifier(nonEmpty: "MyApp")!, accessibility: .whenUnlocked)

// Saving data
myValet.set(string: "super_secret_password", forKey: "userPassword")

// Retrieving data
if let password = myValet.string(forKey: "userPassword") {
print("Retrieved password: \(password)")
}

Advantages:

  • Secure storage
  • Supports multiple platforms
  • Customizable access control

Disadvantages:

  • Dependency on a third-party library

5. SecureEnclave

Overview: SecureEnclave provides additional security by using a hardware-based encryption engine. It can be used with the Keychain for highly sensitive data.

Code Sample:

import Security

// Example function to generate a key in the Secure Enclave
func generateKeyInSecureEnclave() -> SecKey? {
let attributes: [String: Any] = [
kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeySizeInBits as String: 256,
kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
kSecPrivateKeyAttrs as String: [
kSecAttrIsPermanent as String: true,
kSecAttrApplicationTag as String: "com.example.myapp.keys.mykey"
]
]
var error: Unmanaged<CFError>?
return SecKeyCreateRandomKey(attributes as CFDictionary, &error)
}

Advantages:

  • Hardware-based security
  • Enhanced protection for sensitive data

Disadvantages:

  • Limited to devices with Secure Enclave
  • More complex to implement

6. BiometricAuthentication

Overview: BiometricAuthentication leverages Face ID or Touch ID for secure storage and access of sensitive data.

Code Sample:

import LocalAuthentication

func authenticateUser(completion: @escaping (Bool) -> Void) {
let context = LAContext()
var error: NSError?

if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Authenticate to access sensitive data") { success, error in
DispatchQueue.main.async {
completion(success)
}
}
} else {
completion(false)
}
}

Advantages:

  • User-friendly
  • Secure authentication

Disadvantages:

  • Requires biometric hardware
  • Dependency on user consent

7. Data Protection API

Overview: Data Protection API enhances file-level encryption on iOS devices.

Code Sample:

let filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0].appending("/secure_data.txt")
let content = "Sensitive data".data(using: .utf8)!

// Writing data with data protection
do {
try content.write(to: URL(fileURLWithPath: filePath), options: .completeFileProtection)
} catch {
print("Failed to write data: \(error)")
}

Advantages:

  • File-level encryption
  • Enhanced security for stored files

Disadvantages:

  • Limited to file storage
  • Requires device passcode

8. Realm

Overview: Realm is a mobile database that provides encryption for stored data.

Code Sample:

import RealmSwift

// Configure Realm with encryption
let key = Data(count: 64) // Generate a random 64-byte encryption key
let config = Realm.Configuration(encryptionKey: key)
let realm = try! Realm(configuration: config)

// Saving data
let user = User()
user.name = "John Doe"
try! realm.write {
realm.add(user)
}

// Retrieving data
let users = realm.objects(User.self)
for user in users {
print("Retrieved user: \(user.name)")
}

Advantages:

  • Encrypted database
  • Rich query capabilities

Disadvantages:

  • Dependency on a third-party library
  • More complex setup

9. SQLite with Encryption

Overview: SQLite with encryption allows you to use SQLite databases with encrypted data.

Code Sample:

import SQLite

let dbPath = "path/to/database.sqlite"
let db = try Connection(dbPath)

// Setting up encryption key
try db.key("encryption_key")

// Creating a table
let users = Table("users")
let id = Expression<Int64>("id")
let name = Expression<String>("name")
try db.run(users.create { t in
t.column(id, primaryKey: true)
t.column(name)
})

// Inserting data
let insert = users.insert(name <- "John Doe")
try db.run(insert)

// Retrieving data
for user in try db.prepare(users) {
print("id: \(user[id]), name: \(user[name])")
}

Advantages:

  • Familiar SQL syntax
  • Encrypted storage

Disadvantages:

  • Dependency on a third-party library (e.g., SQLite.swift)
  • More complex setup

10. CloudKit

Overview: CloudKit provides secure cloud storage with data encryption in transit and at rest.

Code Sample:

import CloudKit

let container = CKContainer.default()
let privateDatabase = container.privateCloudDatabase

// Creating a record
let record = CKRecord(recordType: "User")
record["name"] = "John Doe" as CKRecordValue

// Saving data
privateDatabase.save(record) { record, error in
if let error = error {
print("Failed to save record: \(error)")
} else {
print("Record saved successfully")
}
}

// Retrieving data
let query = CKQuery(recordType: "User", predicate: NSPredicate(value: true))
privateDatabase.perform(query, inZoneWith: nil) { records, error in
if let error = error {
print("Failed to retrieve records: \(error)")
} else {
if let records = records {
for record in records {
print("Retrieved user: \(record["name"] ?? "Unknown")")
}
}
}
}

Advantages:

  • Secure cloud storage
  • Sync across devices

Disadvantages:

  • Requires network connection
  • Dependency on CloudKit

Conclusion

Selecting the right storage solution for sensitive data in iOS applications depends on your specific needs. While the Keychain remains a robust choice, alternatives like SwiftKeychainWrapper, SAMKeychain, and SecureEnclave offer varied features and ease of use. Always consider the level of security required, ease of implementation, and potential dependencies when choosing the best storage method for your application. By following best practices and leveraging these tools, you can ensure the security of user data in your iOS apps.

--

--

Kalidoss Shanmugam

Experienced mobile app developer with 11 years of expertise, focused on creating innovative solutions that elevate user experiences in today's digital landscap.