In mobile applications, it is sometimes necessary to store information securely on the device. While React Native has the AsyncStorage API for storing data on the device, it is not secure by default, especially on a device that has been jail-broken or has root access.

Before I continue, keep in mind that, on a mobile device, nothing is 100% secure. Any data stored on the phone can be accessed by a determined party. Because they have full control of the device, they can throw whatever computing power they want at cracking any security or encryption.

Libraries

There are a number of third-party libraries that attempt to provide secure storage for React Native. Here are a few that I’ve found:

  • react-native-secure-storage: This library looks promising, but doesn’t seem to be finished yet. The README has installation instructions, but no usage documentation.

  • react-native-keychain: This package looks to be mature and well-maintained, but is “limited to just storing internet and generic passwords”. If that’s all you need, this is a good option.

  • react-native-sensitive-info: This package is also mature and well-maintained. It’s more flexible than react-native-keychain. On iOS, it uses the Keychain for its storage, which is secure. On Android, however, it uses Shared Preferences by default, which are not secure. There is a branch that uses the Android keystore instead; that is secure.

What to Choose?

In a client project I was recently working on, we wanted to be able to store API tokens securely on the device. That ruled out react-native-keychain, so we went with react-native-sensitive-info.

Our application uses Redux, and we were already using redux-persist to store parts of our Redux state tree in AsyncStorage.

redux-persist allows for custom storage engines. As long as a storage engine conforms to the correct API, it can be plugged into redux-persist and used to store the state tree.

We wrote a small adapter layer that allows us to use react-native-sensitive-info as the storage engine for redux-persist.

Our client graciously gave us permission to extract this adapter layer and release it as a standalone library.

The result is redux-persist-sensitive-storage.

Feel free to give it a try in your project.

Here’s a quick example of how to use it:

Example usage
import { compose, applyMiddleware, createStore } from "redux";
import { persistStore, autoRehydrate } from "redux-persist";
import createSensitiveStorage from "redux-persist-sensitive-storage";
const store = createStore(
reducer,
compose(
applyMiddleware(...),
autoRehydrate()
)
);
persistStore(store, {
storage: createSensitiveStorage({
keychainService: "myKeychain",
sharedPreferencesName: "mySharedPrefs"
});
);