Course contentsShow
← React Native
Lesson 133 of 1,5552. Project Scaffolding with ExpoFree lesson

Secure Storage Best Practices

Protect sensitive user tokens using hardware-backed secure enclaves and keystores.

In this lesson, you will learn how to protect sensitive user credentials by leveraging device-level hardware security instead of storing them in plain text.

When building a React Native application, a common mistake is saving sensitive data like authentication tokens or API keys in AsyncStorage. Because AsyncStorage is essentially an unencrypted key-value store, any malicious app or user with file-system access can read that data. To build professional-grade applications, we must offload that sensitive information to the hardware-backed security modules built into modern smartphones.

The Hardware Vault

Both iOS and Android provide a dedicated "Vault"—the Keychain on iOS and the Keystore on Android. These are not just folders in the file system; they are hardware-isolated environments. When you store a token here, the device’s operating system manages the encryption keys. Even if your app is deleted, the data remains securely managed by the hardware enclave, and it can only be decrypted by the app that originally stored it (provided it matches the correct signing certificate).

How to use it in Expo

In an Expo project, we use a library that acts as a bridge to these native systems. It transparently handles the complex native requirements of iOS Keychains and Android Keystores for you.

Here is how you would save a secure token:

import * as SecureStore from 'expo-secure-store';

async function saveUserToken(token) {
  // We save the token under a specific key string
  await SecureStore.setItemAsync('user_auth_token', token);
}

async function getUserToken() {
  // We retrieve it only when needed
  let result = await SecureStore.getItemAsync('user_auth_token');
  return result;
}

Why this is different

Unlike standard local storage, SecureStore does not store your token in a plain text file. By calling setItemAsync, the system passes your data to the native hardware enclave. The hardware encrypts it, stores it, and only returns the decrypted value to your app when requested. This ensures that even if a device is rooted or compromised, the hardware-backed storage remains a significant barrier to attackers trying to steal user sessions.

Key Takeaway: Never store authentication tokens in AsyncStorage; always use hardware-backed storage to ensure your app's sensitive data is encrypted by the device's native secure enclave.