66

I want to store sensitive data locally in a React Native app.

Is the data only available to the app that wrote it?

yogiben
  • 835
  • 1
  • 8
  • 9
  • You can take a look at this post: https://stackoverflow.com/questions/45547657/what-is-the-best-way-to-store-private-data-in-react-native – Julien Kode Aug 09 '17 at 08:06

9 Answers9

53

AsyncStorage is not suitable for storing sensitive information. You might find this useful: https://github.com/oblador/react-native-keychain

It uses facebook conceal/android keystore to store encrypted data to SharedPreferences (Android) and keychain on iOS. (I co-authored the lib). Be sure to read the entire readme to understand what it offers.

vonovak
  • 1,555
  • 2
  • 14
  • 28
  • 2
    Base64 on Android is not a safe way to store data – odemolliens Oct 19 '16 at 09:40
  • 1
    @odemolliens you probably didn't notice that the base64 _encoded_ string that is saved is already *encrypted*. – vonovak Oct 19 '16 at 12:20
  • 1
    I read again source code and you right. But what is the benefit to encode in Base64 if it's already encrypted? cheers – odemolliens Oct 21 '16 at 05:20
  • 5
    The conceal library returns encrypted data as byte array (as far as I remember), not a string. So the byte array is encoded as base64 string and then saved (sharedPreferences do not support saving byte arrays). – vonovak Oct 21 '16 at 17:47
  • 3
    does it play well with expo? – Macilias May 20 '20 at 10:56
18

No , it is not secure since it is not encrypted .I would recommend that you use Expo`s secureStore

If you`re building your app from Expo :

// in managed apps:
import { SecureStore } from 'expo';

If you`re building as a bare app

// in bare apps:
import * as SecureStore from 'expo-secure-store';

Read more here : https://docs.expo.io/versions/v32.0.0/sdk/securestore/

  • 3
    This is the most current and relevant answer. Since the question has been first asked a lot has happened in the ecosystem and the proposed solution above is built into expo and simple to use right out of the box. – Lemmy Figgins Sep 25 '19 at 02:15
13

No, AsyncStorage is not secure for sensitive data. AsyncStorage simply saves data to documents on the phone's hard drive, and therefore anyone with access to the phone's file system can read that data. Of course, whether or not this is problematic for you depends on what you mean by "senstive data."

At least on iOS, it is true that the data is only available to the app that wrote it, because of Apple's sandboxing policy. This doesn't stop jailbroken iPhones with root access to the file system from getting whatever they want, since AsyncStorage does not encrypt any of its data. But in general, don't save sensitive data to AsyncStorage, for the same reason you shouldn't hard code sensitive data in your javascript code, since it can be easily decompiled and read.

Michael Helvey
  • 3,843
  • 22
  • 19
7

For very sensitive app or user data, you could try something like https://github.com/oblador/react-native-keychain on iOS(uses iOS Keychain) or https://github.com/classapp/react-native-sensitive-info for both Android and iOS(uses Android Shared Preference and iOS Keychain).

Both of them come with very fluent API and straightforward way of linking with react-native link and are a more secure way of preserving data you want to keep away from prying eyes.

Aftab
  • 71
  • 1
  • 4
3

I've faced the same problem on a project I was working on, we were using a custom wrapper for AsyncStorage, stored some amount of data and then we tried to retrieve the same data... and it was so easy.

We get over that problem by using Realm with the encryption option and it was a easier, faster and better solution than AsyncStorage.

XaviMorenoM
  • 31
  • 1
  • 2
  • How did you store the Realm key? My belief is it's only possible to store the key hardcoded or locally. – yogiben Aug 29 '16 at 14:30
  • I just wanted my information to be encrypted and it was kind of a Test project so I left it as follows: `let eKey = new Int8Array(64); // pupulate with a secure key` `let realm = new Realm({... encryptionKey: eKey});` – XaviMorenoM Aug 31 '16 at 07:14
  • 2
    You could probably 1. generate a random key when the app first launches. 2. save that to the native keychain using something like react-native-keychain. 3. whenever your app launches thereafter, grab that key from the keychain 4. use the key to obtain your realm instance Note: If the keychain is ever cleared, then you'll need to blow away the realm db. – duhseekoh Jan 02 '17 at 17:23
3

No it is not secure. Consider using library like https://github.com/oblador/react-native-keychain for secure storage.

If you're using Expo you can use Expo.SecureStore to encrypt and securely store key–value pairs locally on the device. Documentation: https://docs.expo.io/versions/latest/sdk/securestore

pyankoff
  • 174
  • 1
  • 5
2

I have created a secure storage module for redux-persist that uses react-native-keychain to store an encryption key and uses CryptoJS to encrypt the redux-store at rest in AsyncStorage. You can find the module at:

redux-persist-encrypted-async-storage

Its usage is discussed in the readme at the link.

Chaudhry Junaid
  • 372
  • 5
  • 15
1

From react-native doc - https://facebook.github.io/react-native/docs/asyncstorage.html

AsyncStorage is a simple, unencrypted, asynchronous, persistent, key-value storage system that is global to the app.

Its not secure as it stores key-value pairs in unencrypted form on device.

It used keychain for iOS and KeyStore for Android for storing data securely.

Community
  • 1
  • 1
pradeep1991singh
  • 8,185
  • 4
  • 21
  • 31
0

If you are still searching for this one.
try using react-native-encrypted-storage they have some encryption.
react-native-encrypted-storage
its so simple as async storage

abhish
  • 243
  • 4
  • 8