You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Windows应用资产安全:如何隐藏或加密Assets文件夹?

Flutter Windows 应用敏感资产加密与保护方案

一、先对敏感资产进行加密

把需要保护的图片、配置文件等用对称加密算法(比如AES)加密,推荐写个简单脚本批量处理,以下是Python脚本示例:

from cryptography.fernet import Fernet
import os

# 生成密钥(仅需生成一次,务必妥善保存)
# key = Fernet.generate_key()
# with open("secret.key", "wb") as key_file:
#     key_file.write(key)

# 加载已生成的密钥
with open("secret.key", "rb") as key_file:
    key = key_file.read()
fernet = Fernet(key)

# 加密指定目录下的文件
def encrypt_assets(source_dir, target_dir):
    os.makedirs(target_dir, exist_ok=True)
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            with open(file_path, "rb") as f:
                data = f.read()
            encrypted_data = fernet.encrypt(data)
            target_path = os.path.join(target_dir, f"{filename}.encrypted")
            with open(target_path, "wb") as f:
                f.write(encrypted_data)

# 调用加密函数,例如加密assets/sensitive目录到encrypted_assets
encrypt_assets("assets/sensitive", "encrypted_assets")

加密后的文件存到独立的encrypted_assets目录,不要放在默认的assets文件夹下。

二、发布构建时排除原敏感Assets目录

  1. 修改pubspec.yaml,只保留非敏感资产路径,移除敏感的assets/sensitive:
flutter:
  assets:
    - assets/public/  # 仅存放公开资源
  1. 写个bat脚本自动化构建与加密文件复制(Windows环境):
@echo off
flutter build windows --release --obfuscate --split-debug-info=./debug_info
xcopy /E /Y encrypted_assets build\windows\runner\Release\encrypted_assets

执行该脚本后,发布包中将只包含加密后的资产,原敏感Assets目录不会被打包进去。

三、运行时解密访问加密资产

在Flutter代码中实现解密逻辑,先在pubspec.yaml添加依赖:encrypt: ^5.0.1,然后编写工具类:

import 'dart:io';
import 'dart:typed_data';
import 'dart:convert';
import 'package:encrypt/encrypt.dart';

class SecureAssetLoader {
  // 注意:密钥不要硬编码,此处仅为示例,实际可通过编译时注入或Windows安全API获取
  static final _key = Key.fromUtf8('your_32_byte_secret_key_here');
  static final _iv = IV.fromUtf8('your_16_byte_iv_here');
  static final _encrypter = Encrypter(AES(_key, mode: AESMode.cbc));

  // 解密指定路径的加密资产
  static Future<Uint8List> loadEncryptedAsset(String relativePath) async {
    final assetPath = Directory.current.path + '/encrypted_assets/' + relativePath;
    final file = File(assetPath);
    if (!await file.exists()) {
      throw Exception('Encrypted asset not found: $relativePath');
    }
    final encryptedBytes = await file.readAsBytes();
    final decryptedBytes = _encrypter.decryptBytes(Encrypted(encryptedBytes), iv: _iv);
    return decryptedBytes;
  }

  // 加载加密图片
  static Future<MemoryImage> loadEncryptedImage(String filename) async {
    final bytes = await loadEncryptedAsset('${filename}.encrypted');
    return MemoryImage(bytes);
  }

  // 加载加密配置文件
  static Future<Map<String, dynamic>> loadEncryptedConfig(String filename) async {
    final bytes = await loadEncryptedAsset('${filename}.encrypted');
    final configString = String.fromCharCodes(bytes);
    return jsonDecode(configString);
  }
}

使用示例:

// 显示加密图片
final imageProvider = await SecureAssetLoader.loadEncryptedImage('sensitive_img.png');
Image(image: imageProvider)

// 读取加密配置
final config = await SecureAssetLoader.loadEncryptedConfig('app_config.json');

四、额外安全强化

  • 开启代码混淆:构建发布版时添加--obfuscate --split-debug-info=./debug_info参数,防止反编译后获取密钥。
  • 密钥与IV不要硬编码,可通过Windows的Data Protection API (DPAPI)加密存储,运行时再解密获取。
  • 加密后的文件使用无意义扩展名(如.bin),避免被直接识别类型。
  • 加密脚本、密钥文件不要提交到版本控制系统,单独加密存储。

内容的提问来源于stack exchange,提问作者Peter Abdo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:22:44