173 lines
5.9 KiB
Swift
173 lines
5.9 KiB
Swift
//
|
|
// EncryptedStorageDemo.swift
|
|
// SecureStorgageSample
|
|
//
|
|
// Demonstrates encrypted file storage with LocalData package.
|
|
//
|
|
|
|
import SwiftUI
|
|
import LocalData
|
|
|
|
struct EncryptedStorageDemo: View {
|
|
@State private var logEntry = ""
|
|
@State private var storedLogs: [String] = []
|
|
@State private var statusMessage = ""
|
|
@State private var isLoading = false
|
|
@State private var iterations = 10_000
|
|
|
|
var body: some View {
|
|
Form {
|
|
Section {
|
|
Text("Encrypted file storage uses AES-256-GCM encryption with PBKDF2 key derivation. Data is encrypted before being written to disk with complete file protection.")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
|
|
Section("Add Log Entry") {
|
|
TextField("Enter log message", text: $logEntry, axis: .vertical)
|
|
.lineLimit(3, reservesSpace: true)
|
|
|
|
Stepper("PBKDF2 Iterations: \(iterations)", value: $iterations, in: 1000...100000, step: 1000)
|
|
.font(.caption)
|
|
|
|
Text("Higher iterations = more secure but slower")
|
|
.font(.caption2)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
|
|
Section("Actions") {
|
|
Button(action: addLogEntry) {
|
|
HStack {
|
|
Image(systemName: "plus.circle.fill")
|
|
Text("Add Encrypted Log Entry")
|
|
}
|
|
}
|
|
.disabled(logEntry.isEmpty || isLoading)
|
|
|
|
Button(action: loadLogs) {
|
|
HStack {
|
|
Image(systemName: "lock.open.fill")
|
|
Text("Decrypt and Load Logs")
|
|
}
|
|
}
|
|
.disabled(isLoading)
|
|
|
|
Button(action: clearLogs) {
|
|
HStack {
|
|
Image(systemName: "trash")
|
|
Text("Clear All Logs")
|
|
}
|
|
}
|
|
.foregroundStyle(.red)
|
|
.disabled(isLoading)
|
|
}
|
|
|
|
if !storedLogs.isEmpty {
|
|
Section("Decrypted Logs (\(storedLogs.count))") {
|
|
ForEach(Array(storedLogs.enumerated()), id: \.offset) { index, log in
|
|
HStack {
|
|
Text("\(index + 1).")
|
|
.foregroundStyle(.secondary)
|
|
Text(log)
|
|
}
|
|
.font(.system(.caption, design: .monospaced))
|
|
}
|
|
}
|
|
}
|
|
|
|
if !statusMessage.isEmpty {
|
|
Section {
|
|
Text(statusMessage)
|
|
.font(.caption)
|
|
.foregroundStyle(statusMessage.contains("Error") ? .red : .green)
|
|
}
|
|
}
|
|
|
|
Section("Encryption Details") {
|
|
LabeledContent("Algorithm", value: "AES-256-GCM")
|
|
LabeledContent("Key Derivation", value: "PBKDF2-SHA256")
|
|
LabeledContent("Iterations", value: "\(iterations)")
|
|
LabeledContent("File Protection", value: "Complete")
|
|
}
|
|
|
|
Section("Key Configuration") {
|
|
LabeledContent("Domain", value: "Encrypted File System")
|
|
LabeledContent("Directory", value: "Caches")
|
|
LabeledContent("Security", value: "AES-256 Encrypted")
|
|
LabeledContent("Platform", value: "Phone Only")
|
|
}
|
|
}
|
|
.navigationTitle("Encrypted Storage")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
}
|
|
|
|
private func addLogEntry() {
|
|
isLoading = true
|
|
Task {
|
|
do {
|
|
let key = StorageKeys.SessionLogsKey(iterations: iterations)
|
|
|
|
// Load existing logs
|
|
var logs: [String]
|
|
do {
|
|
logs = try await StorageRouter.shared.get(key)
|
|
} catch StorageError.notFound {
|
|
logs = []
|
|
}
|
|
|
|
// Add new entry with timestamp
|
|
let timestamp = Date().formatted(date: .abbreviated, time: .standard)
|
|
logs.append("[\(timestamp)] \(logEntry)")
|
|
|
|
// Save encrypted
|
|
try await StorageRouter.shared.set(logs, for: key)
|
|
|
|
storedLogs = logs
|
|
logEntry = ""
|
|
statusMessage = "✓ Entry encrypted and saved"
|
|
} catch {
|
|
statusMessage = "Error: \(error.localizedDescription)"
|
|
}
|
|
isLoading = false
|
|
}
|
|
}
|
|
|
|
private func loadLogs() {
|
|
isLoading = true
|
|
Task {
|
|
do {
|
|
let key = StorageKeys.SessionLogsKey(iterations: iterations)
|
|
storedLogs = try await StorageRouter.shared.get(key)
|
|
statusMessage = "✓ Decrypted \(storedLogs.count) log entries"
|
|
} catch StorageError.notFound {
|
|
storedLogs = []
|
|
statusMessage = "No encrypted logs found"
|
|
} catch {
|
|
statusMessage = "Error: \(error.localizedDescription)"
|
|
}
|
|
isLoading = false
|
|
}
|
|
}
|
|
|
|
private func clearLogs() {
|
|
isLoading = true
|
|
Task {
|
|
do {
|
|
let key = StorageKeys.SessionLogsKey(iterations: iterations)
|
|
try await StorageRouter.shared.remove(key)
|
|
storedLogs = []
|
|
statusMessage = "✓ Encrypted logs cleared"
|
|
} catch {
|
|
statusMessage = "Error: \(error.localizedDescription)"
|
|
}
|
|
isLoading = false
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
NavigationStack {
|
|
EncryptedStorageDemo()
|
|
}
|
|
}
|