Challenge 2: Encrypted Token Storage — Solution class TokenStorage(context: Context) { private val masterKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build() private val prefs = EncryptedSharedPreferences.create( context, "secure_token_prefs", masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) fun saveToken(token: String) { prefs.edit().putString("auth_token", token).apply() } fun getToken(): String? { return prefs.getString("auth_token", null) } } Notes: - The masterKey is generated (or retrieved, if already created previously) via the Android Keystore system — the actual encryption key material never leaves secure hardware storage on supported devices, and is never itself stored inside the encrypted preferences file alongside the data it protects. - Reading and writing (saveToken / getToken) look exactly like plain SharedPreferences usage — putString(...).apply() and getString(...) — with all the actual AES-256 encryption/decryption happening transparently underneath, which is deliberately what makes this API easy to adopt as a drop-in replacement for sensitive values. - getToken() returning String? (nullable) correctly reflects that no token may have been saved yet (e.g. before the user has ever logged in) — the null default passed to getString(...) is the fallback for that case.