diff --git a/README.md b/README.md index 316c698..6c34a0c 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,19 @@ Redux persist storage engine that provides an encryption layer over async storag ### What this project provides This project provides an AES encryption layer (using a randomly generated secure key stored in keychain/keystore) over AsyncStorage for react-native projects + ### To install in your project: -First install `react-native-keychain`. Then: + +```ts +"peerDependencies": { + "@react-native-async-storage/async-storage": "*", + "react-native-keychain": "*", + "crypto-js": "^4.2.0", + "react-native-get-random-values": "^1.11.0", + "uuid": "^11.1.0" + } +``` +First install above peerDependencies, Then: ``` yarn add 'https://github.com/chaudhryjunaid/redux-persist-encrypted-async-storage.git#master' diff --git a/index.js b/index.js index d998336..ff8adc5 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,27 @@ -import { AsyncStorage } from 'react-native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; import * as Keychain from 'react-native-keychain'; -import CryptoJSCore from 'crypto-js/core'; -import AES from 'crypto-js/aes'; - -import uuidv4 from 'uuid/v4'; +/** + * Important Note: Import 'react-native-get-random-values' before [crypto-js,uuid] to avoid crypto, uuid method errors + * https://github.com/uuidjs/uuid#getrandomvalues-not-supported + * [Error: getRandomValues() not supported.] + * [Error: Native crypto module could not be used to get secure random number.] + */ +import 'react-native-get-random-values'; +import CryptoJS from 'crypto-js'; +import { v4 as uuidv4 } from 'uuid'; let encryptionKey = null; -export default ({ service = 'com.redux-persist-encrypted-async-storage' } = {}) => { +export default ({ + service = 'com.redux-persist-encrypted-async-storage', +} = {}) => { const noop = () => null; const getEncryptionKey = async () => { if (encryptionKey == null) { - let { password: encryptionKeyValue } = await Keychain.getGenericPassword({ service }); + let { password: encryptionKeyValue } = await Keychain.getGenericPassword({ + service, + }); + if (!encryptionKeyValue) { encryptionKeyValue = uuidv4(); await Keychain.setGenericPassword('data', encryptionKeyValue, { @@ -32,8 +42,8 @@ export default ({ service = 'com.redux-persist-encrypted-async-storage' } = {}) const encryptedValue = await AsyncStorage.getItem(key); try { const secretKey = await getEncryptionKey(); - const bytes = AES.decrypt(encryptedValue, secretKey); - decryptedString = bytes.toString(CryptoJSCore.enc.Utf8); + const bytes = CryptoJS.AES.decrypt(encryptedValue, secretKey); + decryptedString = bytes.toString(CryptoJS.enc.Utf8); } catch (err) { throw new Error(`Could not decrypt state: ${err.message}`); } @@ -50,7 +60,7 @@ export default ({ service = 'com.redux-persist-encrypted-async-storage' } = {}) let encryptedValue = value; if (value) { const secretKey = await getEncryptionKey(); - encryptedValue = AES.encrypt(value, secretKey).toString(); + encryptedValue = CryptoJS.AES.encrypt(value, secretKey).toString(); } await AsyncStorage.setItem(key, encryptedValue); callback(null); @@ -72,7 +82,8 @@ export default ({ service = 'com.redux-persist-encrypted-async-storage' } = {}) async getAllKeys(callback = noop) { try { - const result = await AsyncStorage.getAllItems(); + // should use getAllKeys() here, not getAllItems() + const result = await AsyncStorage.getAllKeys(); callback(null, result); return result; diff --git a/package.json b/package.json index e52e84f..34284a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redux-persist-encrypted-async-storage", - "version": "1.0.0", + "version": "1.0.1", "description": "Storage engine to provide encryption layer over async storage", "main": "index.js", "scripts": { @@ -30,11 +30,10 @@ "eslint-plugin-react": "^7.12.4" }, "peerDependencies": { - "react-native": "*", - "react-native-keychain": "*" - }, - "dependencies": { - "crypto-js": "^3.1.9-1", - "uuid": "^3.3.2" + "@react-native-async-storage/async-storage": "*", + "react-native-keychain": "*", + "crypto-js": "^4.2.0", + "react-native-get-random-values": "1.11.0", + "uuid": "^11.1.0" } }