Enhancing Data Security in SwiftUI: From UserDefaults to Keychain

Mehrdad Ahmadian
2 min readDec 24, 2023

--

UserDefaults to Keychain

Introduction

In mobile applications, protecting user data is paramount. This article explores two methods of data storage in SwiftUI apps: UserDefaults and Keychain. We’ll start with the insecure UserDefaults method and then shift to the more secure Keychain approach.

Part 1: Storing Data with UserDefaults

What is UserDefaults?

  • UserDefaults is a simple, lightweight mechanism for persisting user preferences and settings.
  • It’s not designed for storing sensitive data, as it lacks encryption.

Implementing UserDefaults in SwiftUI

  • We start by creating a SwiftUI view with a TextField and a "Save" button.
  • The entered data is stored in UserDefaults upon button tap.
import SwiftUI

struct ContentView: View {
@State private var sensitveData = ""

var body: some View {
VStack {
TextField("Enter Sensitive Data", text: $sensitveData)
.textFieldStyle(.roundedBorder)
.padding()

Button("Save Data") {
// Insecure Storage
UserDefaults.standard.setValue(sensitveData, forKey: "SensitiveData")
}
}
.padding()
}
}

#Preview {
ContentView()
}

The Security Flaw

Data stored in UserDefaults can be easily accessed and is not encrypted. Tools like iExplorer can be used to view this data, demonstrating its vulnerability.

Part 2: Securing Data with Keychain

Why Keychain?

  • Keychain’s Security Features
  • Keychain is designed for storing sensitive data such as passwords and tokens.
  • It encrypts data and offers various accessibility options.

Transitioning to Keychain

  • We add a Keychain wrapper library to our project for easy use.
  • Modify the ContentView to use Keychain for data storage.
import KeychainSwift
import SwiftUI

struct ContentView: View {
@State var sensitveData: String
let keychain = KeychainSwift()

var body: some View {
VStack {
TextField("Enter Sensitive Data", text: $sensitveData)
.textFieldStyle(.roundedBorder)
.padding()

Button("Save Data") {
// Securing Data with Keychain
keychain.set(sensitveData, forKey: "SensitiveData", withAccess: .accessibleWhenUnlocked)
}
}
.padding()
}
}

Loading Data on App Launch

  • Fetch sensitive data from Keychain in the app’s entry point and pass it to ContentView.
import SwiftUI
import KeychainSwift

@main
struct Keychain_ExampleApp: App {
let keychain = KeychainSwift()

var body: some Scene {
WindowGroup {

let sensitiveData = keychain.get("SensitiveData") ?? ""
ContentView(sensitveData: sensitiveData)
}
}
}

The Enhanced Security

  • Data stored in Keychain is encrypted and not accessible through file-browsing tools.
  • This demonstrates the increased security of using Keychain over UserDefaults.

Conclusion

Transitioning from UserDefaults to Keychain in SwiftUI apps significantly enhances data security. By implementing Keychain, developers can ensure that sensitive user data is stored safely and is less vulnerable to unauthorized access.

Additional Resources

--

--

Responses (1)