背景
在当今数字化时代,应用数据安全已成为企业和用户最关心的核心问题。为了确保electron应用的数据安全,我设计了一套数据安全存储方案,并通过适配器、工厂模式封装了核心功能,旨在保护用户数据不被篡改和复制,为桌面应用提供了数据保护能力。
简单说就是设计并封装了一套数据安全存储分层架构,实现了对electron应用本地数据存储的防护功能,通过绑定机器码包装数据可以做到数据加密、防篡改、防复制的功能。
详细讲解和效果可以移步看这里:
我用Electron实现了:本地数据加密+防复制篡改!这才是真正的安全方案
功能特性
- 解耦设计:安全层和数据存储层分离
- 适配器模式:可插拔任何存储后端
- 可单独开关加密、签名、机器绑定
- 兼容electron-store:无缝迁移
- 易于拓展
文件结构
├── adapters // 存储适配器
│ ├── baseAdapter.ts
│ └── electronStoreAdapter.ts
│ └── fileStorageAdapter.ts
├── security // 安全层
│ ├── machineFingerprint.ts
│ ├── securityMiddleware.ts
├── index.ts // 入口文件
└── secureStore.ts // 安全存储类
Electron 数据安全存储分层架构设计(防篡改/复制)
数据流转
整个加密存储过程中的数据流转过程:在应用层的界面中可以通过store.set存储你想要设置的key:value格式数据,从应用层到内存是明文格式的。
在安全层的securityMiddleware会处理指纹、时间戳、签名、加密,最后将包装好的数据序列化为字符串作为payload进行加密,得到密文,再补充签名。
通过adapter.set在存储层落盘到文件,最终格式如下。
// 应用层 -> 内存明文
store.set('key', {
key: 'value',
user: 'username',
})
// 安全层 -> 内存密文
securityMiddleware 处理指纹、时间戳、签名、加密
const wrapped = {
data: {},
fingerprint: 'xxxx',
timestamp: Date.now()
}
将wrapped数据序列化为字符串,作为payload进行加密,得到密文,再补充签名
// 存储层 -> 磁盘文件
adapter.set()
// 最终落盘数据格式,license为存储key
{
"license": {
"payload": "xxxxxxxx",
"signature": "yyyyyyyy",
}
}
关于用户是否能解密payload?
攻击难度分析:加密算法是AES-256-GCM,密钥长度256位(32字节),暴力破解需要2^256次尝试, 假设每秒尝试10^18次,需要2^256 / 10^18秒,结论是暴力破解在物理上不可能。
存储密钥的位置是关键弱点
- 硬编码在应用程序中,风险较高。asar解包后直接看到。
- 密钥从机器信息派生,风险中,解密需要逆向分析
- 存储在native模块+混淆。风险低,解密需要专业逆向工程,需要专业技能。
- 存储存储在服务器,风险极低,解密极难。
手动修改文件场景
- 修改payload内容,会被检测到,提示签名无效(✅ 已验证)
- 修改签名signature,payload有效,会被检测到,提示签名无效(✅ 已验证)
- 删除整个配置文件内容,会被检测到,重新初始化空对象/默认值(✅ 已验证)
- 删除整个配置文件,会被检测到,重新创建配置文件,包含默认值(✅ 已验证)
- 从其他电脑机器复制配置文件,会被检测到,提示机器指纹验证失败(✅ 已验证)