React Native redux-persist加密密钥生成

3
我正在构建一个使用`redux-persist`和`redux-persist-transform-encrypt`来加密存储设备上应用状态的React Native应用程序。`redux-persist-transform-encrypt`使用`CryptoJs`通过AES加密数据:`CryptoJS.AES.encrypt('serialized app state', 'some-secret-key')`。
我的问题是:(我是一个加密新手),生成`some-secret-key`是否有最佳实践?我的计划是在应用程序首次启动时随机生成此密钥并将其安全地存储在设备钥匙串中。

这绝对不是一个答案,但是这个讨论可能会帮助你澄清这个话题。 - Diego Couto
2个回答

1
我们使用React Native Keychain来存储随机生成的密钥,以确保即使攻击者可以访问文件系统,也很难获取该密钥。
let secretKey

async function getSecretKey() {
  let {password} = await Keychain.getGenericPassword()
  if (!password) {
    password = generateRandomKey()
    await Keychain.setGenericPassword(appName, password)
  }
  return password
}

const encrypt = async function(state) {
  if (!secretKey) {
    secretKey = await getSecretKey()
  }

  if (typeof state !== 'string') {
    state = stringify(state);
  }

  return CryptoJS.AES.encrypt(state, secretKey).toString()
}

react-native-keychain 是一个存储库吗?我正在使用 redux-persist,除了 AsyncStorage,我不知道在哪里存储加密数据。 - Ken Pham

0

你可以使用一些uuid生成器来生成随机的密钥,然后像@jimchao所说的那样将其存储在keychain中。如果你正在使用expo,你可以编写如下内容:

import Expo from 'expo';

export const getFromSecureStore = (key, options) =>
  Expo.SecureStore.getItemAsync(key, options);

export const saveToSecureStore = (key, value, options) =>
  Expo.SecureStore.setItemAsync(key, value, options);

然后将其用作:

// 在登录时

function* handleSignInRequest(action) {
  try {
    const resp = yield RequestService.post(
      action.payload.url,
      action.payload.body,
    );
    yield put({ type: SIGN_IN_SUCCEEDED, payload: resp.data });
    const { username, password } = action.payload.body;
    yield saveToSecureStore('username', username, {
      keychainAccessible: Expo.SecureStore.ALWAYS, // can be changed as per usage
    });
    yield saveToSecureStore('password', password, {
      keychainAccessible: Expo.SecureStore.ALWAYS,
    });
  } catch (error) {
    console.log('======>>  signin error', error);
    yield put({ type: SIGN_IN_FAILED, error: error.response });
  }
}

// 在应用启动时

async handleSignInAtBootstrap() {
    try {
      const username = await getFromSecureStore('username');
      const password = await getFromSecureStore('password');
      this.props.signInUser(username, password); //dispatch an action
    } catch (error) {
      console.log('======>>>', error);
    }
  }

这里是Expo安全存储文档,可以探索各种配置


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接