Adding ability to encrypt storage data
Do you have near term plans to incorporate encryption onto the storage data? https://github.com/jas-/crypt.io
In this case, we could pass an additional attribute in the persistConfig to persist the data with encryption (The flag could either be the machine's UUID or a user set passphrase)
var pass = window.prompt("Please enter password...", "a custom password");
var persistConfig = {
passphrase: pass
};
persistStore(store, config, callback);
I think this can be achieved today using https://github.com/maxdeviant/redux-persist-transform-encrypt, although that uses crypto-js not crypt.io.
Looking at crypt.io it I think could work with some adaptation, but the one method it is missing is getAllKeys. This could theoretically be achieved by saving a separate known key which stores all other keys, but that would require some adaptation in redux-persist core. Open to PRs!
I've implemented the idea @rt2zz earlier and it's working quite well (it passes security audits). For iOS we use a passphrase stored in the KeyChain on Android on KeyStore. With that passphrase we encrypt/decrypt data via redux-persist.
Two things to keep in mind
- crypto-js is slow, especially with huge data sets stored on device, a off js thread will be cool to have
- lock/reboot iOS locks the keychain, you need to adjust settings to make the keychain available on any time (otherwise your app won't be able to decrypt the data on the background (e.g. via a geofence event or background-fetch execution time process)
Planning to make this mechanism open-source, as it's battle tested for some months now in different production apps.
@robmoorman wow very interested in your implementation. is it materially different from https://github.com/maxdeviant/redux-persist-transform-encrypt ?
As for lock/reboot locking the keychain is there a workaround? do you keep the data you need in the background in a non-encrypted store?
Hi @rt2zz it's an addition to https://github.com/maxdeviant/redux-persist-transform-encrypt as the secretKey comes from the KeyChain/KeyStore (auto-generated by the device), so it's not stored in the JS bundle on device.
There is a setting for iOS, yes. To adjust that the keychain can be accessed in this case. I used this, but you can see what the settings is like: https://github.com/oblador/react-native-keychain/blob/master/RNKeychainManager/RNKeychainManager.m#L85
More info here: https://developer.apple.com/reference/security/ksecattraccessiblealways
I'll inform you when this package is ready (need it for a project right now, so planning to make it open-source).
@robmoorman any progress on your project?
@robmoorman i am also interested in your approach. Any possibilies you can share some more information? 👍
He @patrickkempff haven't got the time (yet) to work on this. You can watch my eact-native-redux-secure-storage repo, I'll place it over there.
I missed it the first time I read the readme, but if you're on react native redux-persist-sensitive-storage also looks like a good candidate.
@robmoorman Have you had a chance to open source your react-native-redux-secure-storage?
Here is a very simple implementation using react-native-keychain: https://gist.github.com/patrickkempff/86f44f017568a973f5c041b205e4365c
I need to encrypt all my reducers using redux-persist (in that I am using persist-store) in which all my data is stored in browser local-storage. When I see my browser local-storage, I should able to see my data encrypted, once it gets passed from persist-store and stored into local-storage.
Can you please help me with some examples.
I ended up building my own adapter/library for Redux Persist because I was running into a couple of recurring issues:
AsyncStorage size limits that caused problems with larger persisted states.
Lack of atomicity in some existing persistence libraries, which occasionally led to data loss or corruption.
The result is react-native-blob-persist — a file‑based storage solution that adds extra operations to ensure atomic writes and automatic retries in case of unexpected issues.
Right now, I already have wrappers in place for compression/decompression, which helps a lot with large states. Encryption wrappers are on the roadmap, and I’d love to collaborate with anyone interested in helping shape and implement that part.
If this sounds useful for your projects, feel free to give it a try — and if you’d like to contribute, especially around the encryption feature, your help would be super welcome 🙏