Platform-Specific Secure Storage

Platform-Specific Secure Storage

Each platform provides specialized secure storage mechanisms that leverage hardware security features.

iOS Keychain Services Deep Dive:

// Advanced Keychain implementation with access control
import Security
import LocalAuthentication

class KeychainService {
    
    enum KeychainError: Error {
        case duplicateItem
        case itemNotFound
        case invalidData
        case authenticationFailed
        case unexpectedError(OSStatus)
    }
    
    // Save data with biometric protection
    func saveSensitiveData(
        _ data: Data,
        service: String,
        account: String,
        requiresBiometric: Bool = true
    ) throws {
        
        var query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: service,
            kSecAttrAccount as String: account,
            kSecValueData as String: data
        ]
        
        if requiresBiometric {
            var error: Unmanaged<CFError>?
            let accessControl = SecAccessControlCreateWithFlags(
                kCFAllocatorDefault,
                kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
                [.biometryCurrentSet],
                &error
            )
            
            if let accessControl = accessControl {
                query[kSecAttrAccessControl as String] = accessControl
            } else if let error = error {
                throw error.takeRetainedValue() as Error
            }
        } else {
            query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
        }
        
        // Delete any existing item
        SecItemDelete(query as CFDictionary)
        
        // Add new item
        let status = SecItemAdd(query as CFDictionary, nil)
        
        guard status == errSecSuccess else {
            throw KeychainError.unexpectedError(status)
        }
    }
    
    // Retrieve data with authentication
    func retrieveSensitiveData(
        service: String,
        account: String,
        authenticationPrompt: String
    ) throws -> Data {
        
        let context = LAContext()
        context.localizedReason = authenticationPrompt
        
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: service,
            kSecAttrAccount as String: account,
            kSecReturnData as String: true,
            kSecMatchLimit as String: kSecMatchLimitOne,
            kSecUseAuthenticationContext as String: context
        ]
        
        var result: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &result)
        
        guard status == errSecSuccess else {
            if status == errSecItemNotFound {
                throw KeychainError.itemNotFound
            } else {
                throw KeychainError.unexpectedError(status)
            }
        }
        
        guard let data = result as? Data else {
            throw KeychainError.invalidData
        }
        
        return data
    }
}

Android Encrypted SharedPreferences and DataStore:

// Modern secure storage with DataStore
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import androidx.security.crypto.EncryptedFile
import androidx.security.crypto.MasterKeys
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.io.File

class SecureDataStore(private val context: Context) {
    
    // Create encrypted DataStore
    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
        name = "secure_prefs",
        produceMigrations = { context ->
            listOf(
                EncryptedSharedPreferencesMigration(context)
            )
        }
    )
    
    // Define keys
    companion object {
        val USER_TOKEN = stringPreferencesKey("user_token")
        val USER_ID = intPreferencesKey("user_id")
        val BIOMETRIC_ENABLED = booleanPreferencesKey("biometric_enabled")
    }
    
    // Save encrypted data
    suspend fun saveUserToken(token: String) {
        context.dataStore.edit { preferences ->
            preferences[USER_TOKEN] = token
        }
    }
    
    // Retrieve encrypted data
    val userToken: Flow<String?> = context.dataStore.data
        .map { preferences ->
            preferences[USER_TOKEN]
        }
    
    // Encrypted file operations
    fun saveSecureFile(filename: String, content: ByteArray) {
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
        
        val file = File(context.filesDir, filename)
        val encryptedFile = EncryptedFile.Builder(
            file,
            context,
            masterKeyAlias,
            EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
        ).build()
        
        encryptedFile.openFileOutput().use { output ->
            output.write(content)
        }
    }
    
    fun readSecureFile(filename: String): ByteArray {
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
        
        val file = File(context.filesDir, filename)
        val encryptedFile = EncryptedFile.Builder(
            file,
            context,
            masterKeyAlias,
            EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
        ).build()
        
        return encryptedFile.openFileInput().use { input ->
            input.readBytes()
        }
    }
}