Keystore and Keychain

The Android Keystore and iOS Keychain

The Android Keystore holds keys, not data: an app has it generate a key under an alias and asks it to encrypt or decrypt, but never sees the key material, which on most phones lives in a Trusted Execution Environment or StrongBox chip. The iOS Keychain stores the small secrets themselves, released to the app according to an accessibility class. Either can demand a fingerprint, face or passcode first.

Where the operating systems keep secrets
Android Keystore iOS Keychain
Stores Keys; your ciphertext lives in a normal file The secret itself
Hardware TEE or StrongBox, where present Secure Enclave protects the keys
Access rules KeyGenParameterSpec, e.g. user authentication required Accessibility, e.g. WhenUnlocked
Biometric binding setUserAuthenticationRequired(true, ...) Access control such as .biometryCurrentSet

A WebView reaches neither, so secure storage always means a plugin. On Android the usual pattern, used by both plugins in the next section, is an AES-GCM key generated in the Keystore that encrypts values which are then written to an ordinary SharedPreferences file. Google's own wrapper for this, EncryptedSharedPreferences in androidx.security:security-crypto, is now deprecated: version 1.1.0-beta01 (June 2025) deprecated all its APIs "in favour of existing platform APIs and direct use of Android Keystore", so prefer plugins that call the Keystore directly.