背景
在之前的一个项目中,我们发现了一个中等程度的安全性问题。这个问题的核心在于,我们的APP在缓存中存储了一些敏感信息和安全性数据。更严重的是,Android版本的APP存在一个安全漏洞,允许攻击者通过模拟器运行APP来获取缓存中的数据,从而威胁到用户的安全。
为了彻底解决Android版本APP存在的这一问题,我们决定对缓存中存储的所有数据进行加密处理。这样,即使攻击者能够获取到缓存数据,也无法轻易地读取或使用其中的敏感信息,大大提高了数据的安全性。
项目背景
-
React Native
-
Android & IOS
-
NodeJS
问题复现
准备环境
工具
- Homebrew
- ADB(Android Debug Bridge)
- Android Studio
安装ADB
ADB全称为Android Debug Bridge,起到调试桥的作用,是一个客户端-服务器端程序。在这个场景中,ADB作为一种用于与安卓设备进行通信的命令行工具,我们可以使用其在模拟器中执行各种调试和测试操作。
在Mac电脑上可以使用Homebrew一键式安装ADB,在命令行执行下述命令即可:
brew install android-platform-tools
模拟器中运行APP
对于react-natvie的app项目来说,可以使用如下的命令运行Andriod版本:
react-native run-android
复现方式
- 查看运行中的andriod设备
adb devices -l
- 进入模拟器Shell环境
adb shell
- 查看缓存文件(在Shell中执行)
//查看缓存文件列表
run-as APP包名 ls /data/data/APP包名/databases/
//查看缓存数据内容
run-as APP包名 cat /data/data/APP包名/databases/RKStorage
执行后可以看到该APP缓存中的文件,以及RKStorage文件中的内容,这里就不截图给大家看了。经过确认,该缓存文件中确实包含了很多隐私信息和安全信息,这些信息都是应该被加密保存的。
那么接下来我们就对这些数据进行加密后再存储,这样就算可以查看到缓存文件的内容,也无法查看到明文数据。
解决方案与实现
解决方案
使用AES加密方式对数据内容加密,加密后再存储在缓存中。当使用缓存的数据时,将数据解密后再使用。这样就可以保证数据的安全性,确保无法从缓存中直接查看到数据。
实现
为了在React Native中使用AES加密,最后选择使用三方包
来实现数据加密和解密。crypto-js
具体可参考crypto-js的github:https://github.com/brix/crypto-js
引入依赖
npm install crypto-js
加密/解密方法
import CryptoJS from 'crypto-js';
//定义AES加密的key和iv
let key = CryptoJS.enc.Utf8.parse('XXX');
let iv = CryptoJS.enc.Utf8.parse('XXX')
//解密方法
export const decrypt = (data) => {
let decrypt = CryptoJS.AES.decrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Utf8.stringify(decrypt)
}
//加密方法
export const encrypt = (data) => {
let encrypted = CryptoJS.AES.encrypt(data, key, {iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
}
在定义了加密和解密方法后,将数据放入内存时需要执行
方法后再存储数据,比如:encrypt
//将userInfo数据加密后存放到缓存中,命名为user
AsyncStorage.setItem('user', encrypt(userInfo));
这样存储到缓存中的数据就是加密后的数据,使用时再执行
方法后再使用数据,比如:decrypt
//将缓存中名为user的数据解密
let userInfo = decrypt(AsyncStorage.getItem('user'))
留言