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目录
- 修改
pubspec.yaml,只保留非敏感资产路径,移除敏感的assets/sensitive:
flutter: assets: - assets/public/ # 仅存放公开资源
- 写个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
相关产品推荐
相关产品推荐

