electron 数据安全加密存储-防篡改防复制

40 阅读3分钟

背景

在当今数字化时代,应用数据安全已成为企业和用户最关心的核心问题。为了确保electron应用的数据安全,我设计了一套数据安全存储方案,并通过适配器、工厂模式封装了核心功能,旨在保护用户数据不被篡改和复制,为桌面应用提供了数据保护能力。

简单说就是设计并封装了一套数据安全存储分层架构,实现了对electron应用本地数据存储的防护功能,通过绑定机器码包装数据可以做到数据加密、防篡改、防复制的功能。

image.png

详细讲解和效果可以移步看这里:

我用Electron实现了:本地数据加密+防复制篡改!这才是真正的安全方案

功能特性

  1. 解耦设计:安全层和数据存储层分离
  2. 适配器模式:可插拔任何存储后端
  3. 可单独开关加密、签名、机器绑定
  4. 兼容electron-store:无缝迁移
  5. 易于拓展

文件结构

├── adapters                          // 存储适配器
│   ├── baseAdapter.ts
│   └── electronStoreAdapter.ts
│   └── fileStorageAdapter.ts
├── security                          // 安全层
│   ├── machineFingerprint.ts
│   ├── securityMiddleware.ts
├── index.ts                          // 入口文件
└── secureStore.ts                    // 安全存储类

Electron 数据安全存储分层架构设计(防篡改/复制)

electron-secure.png

数据流转

整个加密存储过程中的数据流转过程:在应用层的界面中可以通过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秒,结论是暴力破解在物理上不可能。

存储密钥的位置是关键弱点

  1. 硬编码在应用程序中,风险较高。asar解包后直接看到。
  2. 密钥从机器信息派生,风险中,解密需要逆向分析
  3. 存储在native模块+混淆。风险低,解密需要专业逆向工程,需要专业技能。
  4. 存储存储在服务器,风险极低,解密极难。

手动修改文件场景

  1. 修改payload内容,会被检测到,提示签名无效(✅ 已验证)
  2. 修改签名signature,payload有效,会被检测到,提示签名无效(✅ 已验证)
  3. 删除整个配置文件内容,会被检测到,重新初始化空对象/默认值(✅ 已验证)
  4. 删除整个配置文件,会被检测到,重新创建配置文件,包含默认值(✅ 已验证)
  5. 从其他电脑机器复制配置文件,会被检测到,提示机器指纹验证失败(✅ 已验证)