我正在构建一个React Native应用,它使用的是 redux-persist
和 redux-persist-transform-encrypt
以在设备上加密存储应用状态。redux-persist-transform-encrypt
使用 CryptoJs
通过AES加密数据。CryptoJS.AES.encrypt('serialized app state', 'some-secret-key')
.
我的问题是 (我是个加密新手)有没有一个最好的方法来生成... ... some-secret-key
? 我的计划是在应用第一次启动时随机生成这个密钥,并将其安全地存储在设备钥匙链中。
我们使用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()
}
你可以使用一些uuid生成器来生成随机的秘钥,然后按照@jimchao的说法把它存储在钥匙链中。如果你使用的是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);
}
}
这里 博览会安全存储文件 来探索各种配置