Managing App Secrets with Xamarin.Essentials SecureStorage
Learn how to use Xamarin.Essentials SecureStorage to handle tokens and secrets across iOS and Android, including platform mechanics, code examples, and critical limits.
29 Jun 2026, 08:39 UTC

The Problem: Cross-Platform Secret Storage
Storing sensitive data like OAuth tokens, API keys, or user passwords in plaintext preferences is a security risk. Each mobile platform has a different mechanism for secure storage: iOS uses the Keychain, and Android uses the Keystore. Writing separate implementations for each platform is time-consuming and error-prone.
The solution is Xamarin.Essentials.SecureStorage. It provides a unified asynchronous API that maps to the native secure storage of each platform, ensuring that secrets are encrypted at rest without requiring the developer to manage low-level cryptographic keys.
How the Mechanism Works
SecureStorage does not implement its own encryption algorithm; instead, it acts as a wrapper for platform-specific secure containers:
- iOS: It writes a
kSecClassGenericPassworditem to the iOS Keychain. These items are encrypted and managed by the OS. - Android (API 23+): It uses
EncryptedSharedPreferences. The encryption keys for the preferences file are themselves stored in the Android Keystore, ensuring the plaintext never touches standard app storage. - UWP: It utilizes the DataProtection API to encrypt values before storage.
Implementation Example
To use SecureStorage, ensure the Xamarin.Essentials NuGet package is installed. All operations are asynchronous to avoid blocking the UI thread during disk I/O or cryptographic operations.
using Xamarin.Essentials;using System.Threading.Tasks;using System;
public class TokenService
{
private const string TokenKey = "oauth_access_token";
public async Task SaveToken(string token)
{
try
{
// Store the secret securely
await SecureStorage.SetAsync(TokenKey, token);
}
catch (Exception ex)
{
// Handle potential platform-specific crypto failures
Console.WriteLine($"Error saving token: {ex.Message}");
}
}
public async Task<string> GetToken()
{
// GetAsync returns null if the key is not found
string token = await SecureStorage.GetAsync(TokenKey);
return token;
}
public void ClearToken()
{
SecureStorage.Remove(TokenKey);
}
}
Critical Check: Notice that GetAsync returns null if the key does not exist. You must implement a null check in your business logic rather than expecting a KeyNotFoundException.
Operational Limits
| Limit | Detail |
|---|---|
| Data Size | Designed for small strings (tokens/passwords). Do not store large JSON blobs or files here. |
| Android Version | Requires Android 6.0 (API 23) or newer. Older versions will throw a FeatureNotSupportedException. |
| Persistence | On Android, uninstalling the app deletes the data. On iOS, Keychain items can persist after uninstall. |
Common Engineering Mistakes
- Ignoring SecureStorageException: On Android, hardware-backed keystore failures can occur. Always wrap
SetAsyncandGetAsyncin try/catch blocks to handleSecureStorageException. - Assuming Symmetric Behavior: Developers often assume that clearing the app's data or uninstalling it wipes all secrets. Because iOS Keychain items can survive an uninstall, you may need a manual "First Run" check to clear old tokens.
- Blocking the Thread: Using
.Resultor.Wait()on these async methods can lead to deadlocks, especially on the Android main thread.
Verification and Migration
To verify that data is not stored in plaintext on Android, you can use the Android Debug Bridge (ADB) to inspect the preferences file:
# Run as the app user to access private data
adb shell run-as your.package.name cat /data/data/your.package.name/shared_prefs/Xamarin.Essentials.SecureStorage.xml
The resulting XML should contain base64-encoded ciphertext, not your plaintext token.
Legacy Notice: Xamarin and Xamarin.Essentials reached end-of-support on May 1, 2024. For new development, migrate to .NET MAUI. The equivalent API is Microsoft.Maui.Essentials.SecureStorage, which maintains a nearly identical method signature, making the transition straightforward.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.