# Python Module Bank - SQLite 模块打包系统 一个将 Python 模块打包到 SQLite 数据库,并支持从数据库直接导入模块的工具系统。支持 **AES 字节码加密** 和 **PyArmor 代码混淆** 双重保护机制。 ## 🌟 特性 - **单文件分发** - 将所有模块打包到单个 SQLite 数据库文件 - **AES 字节码加密** - 编译后的字节码使用 Fernet (AES-128-CBC) 加密存储 - **PyArmor 代码混淆** - 支持使用 PyArmor 对 Python 源代码进行混淆保护 - **双层保护** - 可同时使用 PyArmor 混淆 + AES 字节码加密,提供双重安全保障 - **动态导入** - 运行时直接从数据库加载模块,无缝集成 Python 导入系统 - **完整包支持** - 支持包结构和子模块导入 - **CLI 工具** - 提供完整的命令行接口 ## 📦 安装 ### 从源码安装 ```bash git clone http://124.71.68.6:3000/chakcy/module_bank.git cd module-bank pip install -e . ``` ### 使用 uv(推荐) ```bash git clone http://124.71.68.6:3000/chakcy/module_bank.git cd module-bank uv sync ``` ### 可选依赖 - **PyArmor** (强烈推荐): `uv add pyarmor` 或 `pip install pyarmor` - 为模块提供 Python 源代码级别的混淆保护 - 商业版可去除试用版水印 ## 🚀 快速开始 ### 1. 创建示例模块 ```python # my_package/__init__.py def hello(): print("Hello from my_package!") return "success" VERSION = "1.0.0" ``` ```python # my_package/utils.py def add(a, b): return a + b ``` ### 2. 打包模块到数据库 #### 使用 AES 加密(推荐) ```bash # 生成密钥并打包 mbank pack my_package --db my_package.mbank --key "$(python -c "from module_bank.encryption import Encryption; print(Encryption.generate_key())")" ``` #### 使用 PyArmor 混淆 ```bash # 使用 PyArmor 保护源代码 mbank pack my_package --db my_package.mbank --pyarmor ``` #### 使用双层保护 ```bash # PyArmor 混淆 + AES 加密 mbank pack my_package --db my_package.mbank --pyarmor --key "your-encryption-key" ``` ### 3. 从数据库导入 ```python # import_example.py from module_bank.python_to_sqlite import PythonToSQLite packer = PythonToSQLite("my_package.mbank") finder = packer.install_importer(key="your-encryption-key") # 如果加密了需要提供密钥 from my_package import utils from my_package import hello print(hello()) print(utils.add(3, 4)) ``` ## 🛡️ 安全保护机制 ### 第一层:PyArmor 代码混淆 PyArmor 对 Python 源代码进行混淆,将代码转换为难以阅读和逆向的形式: - 混淆后的代码依赖运行时二进制文件(`.pyd`/`.so`),无法直接运行 - 支持混淆级别控制(代码混淆、模块混淆) - 运行时文件会自动存储在数据库中,加载时自动部署 ```bash # 高级混淆选项 mbank pack my_module.py --name my_module --db modules.db \ --pyarmor \ --pyarmor-obf-code 1 \ --pyarmor-obf-mod 1 ``` ### 第二层:AES 字节码加密 编译后的字节码使用 Fernet (AES-128-CBC) 加密: ```bash # 生成密钥 python -c "from module_bank.encryption import Encryption; print(Encryption.generate_key())" > my_key.key # 使用密钥打包 mbank pack my_module.py --name my_module --db modules.db --key "$(cat my_key.key)" # 使用时提供密钥 mbank install --db modules.db --key "$(cat my_key.key)" ``` ### 安全建议 1. **密钥管理**:加密密钥不要硬编码在代码中,使用环境变量或密钥管理服务 2. **删除源代码**:打包后可从数据库删除源代码,仅保留混淆后的代码: ```bash # 删除所有模块的源代码 mbank delete_source --db modules.db # 删除指定模块的源代码 mbank delete_source --db modules.db --module my_module ``` ## 📖 详细使用 ### 命令行工具 ```bash # 打包单个模块 mbank pack my_module.py --name my_module --db modules.db # 打包整个目录(自动识别包结构) mbank pack my_package/ --db modules.db # 使用 PyArmor 混淆打包 mbank pack my_module.py --name my_module --db modules.db --pyarmor # 使用 AES 加密打包 mbank pack my_module.py --name my_module --db modules.db --key "your-key" # 双层保护 mbank pack my_module.py --name my_module --db modules.db --pyarmor --key "your-key" # 列出数据库中的模块 mbank list --db modules.db # 删除源代码 mbank delete_source --db modules.db mbank delete_source --db modules.db --module my_module # 安装导入器并进入交互模式 mbank install --db modules.db mbank install --db modules.db --key "your-key" ``` ### 编程接口 #### 打包模块 ```python from module_bank import PythonToSQLite from module_bank.encryption import Encryption # 生成加密密钥 key = Encryption.generate_key() # 使用 AES 加密打包 packer = PythonToSQLite("modules.mbank", key=key) # 或使用 PyArmor 混淆打包 packer = PythonToSQLite( "modules.mbank", pyarmor_obfuscate=True, pyarmor_obf_code=1, pyarmor_obf_mod=1, ) # 打包单个模块 packer.pack_module("module.py", "module_name") # 打包整个目录(自动识别包结构) packer.pack_directory("my_package/") # 验证包结构 packer.verify_package_structure() ``` #### 导入模块 ```python from module_bank import PythonToSQLite # 如果数据库中的模块被 AES 加密了,需要提供密钥 packer = PythonToSQLite("modules.mbank") # 安装导入器到 sys.meta_path finder = packer.install_importer(key="your-key") # 列出所有可用模块 modules = packer.list_modules() for module in modules: package_flag = " [包]" if module["is_package"] else "" print(f" - {module['module_name']}{package_flag}") # 直接导入数据库中的模块(就像普通模块一样) import my_package import my_package.submodule print(my_package) my_package.hello() ``` ## 🏗️ 架构设计 ### 核心组件 ```python src/module_bank/ ├── python_to_sqlite.py # 主打包类 ├── sqlite_module_importer.py # 数据库存储管理器 ├── sqlite_meta_path_finder.py # 元路径查找器 ├── sqlite_module_loader.py # 模块加载器 ├── encryption.py # AES 密钥管理 ├── pyarmor_encryption.py # PyArmor 混淆封装 ├── cli.py # 命令行接口 └── __init__.py # 模块导出 ``` ### 数据流 ```text 1. 打包阶段: .py 文件 → (可选: PyArmor 混淆) → 编译为字节码 → (可选: AES 加密) → 存储到 SQLite 2. 导入阶段: 导入请求 → MetaPathFinder 查找 → ModuleLoader 加载 → (AES 解密) → (PyArmor 运行时部署) → 执行模块 ``` ### 数据库模式 ```sql -- 模块表 CREATE TABLE python_modules ( module_name TEXT PRIMARY KEY, source_code TEXT, -- 源代码(PyArmor 混淆后) bytecode BLOB, -- 编译后的字节码(可选 AES 加密) is_package BOOLEAN, -- 是否是包 metadata TEXT, -- 元数据(JSON 格式) encrypted INTEGER DEFAULT 0, -- AES 是否已加密 pyarmor_protected INTEGER DEFAULT 0, -- 是否已 PyArmor 混淆 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- PyArmor 运行时存储表 CREATE TABLE pyarmor_runtime ( id INTEGER PRIMARY KEY AUTOINCREMENT, runtime_name TEXT UNIQUE NOT NULL, pyd_data BLOB, -- 原生二进制文件(.pyd/.so) init_data TEXT, -- __init__.py 内容 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` ## 🔧 高级功能 ### 排除模式 ```python # 打包时排除特定文件 packer.pack_directory( "my_project/", exclude_patterns=["*_test.py", "*.pyc", "__pycache__"], ) ``` ### 元数据存储 ```python # 为模块添加元数据 packer.importer.add_module( "my_module", source_code, is_package=False, metadata={"version": "1.0", "author": "me"}, ) ``` ### 混合导入 ```python # 数据库导入器默认插入到 meta_path 开头,优先级高于文件系统 import sys from module_bank import PythonToSQLite packer = PythonToSQLite("modules.db") finder = packer.install_importer() # 如果需要文件系统优先,将查找器追加到末尾 sys.meta_path.remove(finder) sys.meta_path.append(finder) ``` ### 验证运行时完整性 ```python from module_bank.sqlite_module_importer import SQLiteModuleImporter importer = SQLiteModuleImporter("modules.db") runtimes = importer.list_runtimes() for rt in runtimes: print(f"运行时: {rt['runtime_name']} (创建于: {rt['created_at']})") ``` ## ⚠️ 注意事项 ### 安全性 - 模块字节码直接执行,确保数据库来源可信 - AES 加密密钥必须安全保管,丢失后将无法解密模块 - PyArmor 混淆提供源代码级别的保护,但商业版才能去除试用版水印 - 生产环境建议 PyArmor 混淆 + AES 加密同时使用 ### 兼容性 - 字节码不跨 Python 版本兼容(3.12 编译的模块无法在 3.11 加载) - 不支持 C 扩展模块 - PyArmor 运行时文件与操作系统相关(Windows 用 `.pyd`,Linux 用 `.so`) - 运行时文件需在目标系统上重新打包 ### 性能 - **启动时**:有一次性数据库查询和反序列化/运行时部署开销 - **运行时**:与传统导入性能相同(使用 sys.modules 缓存) - **最佳适用**:长期运行的服务、桌面应用 ### 更新模块 ```python # 重新打包会自动更新 packer.pack_module("updated_module.py", "module_name") ``` ### 删除模块 ```sql -- 直接从数据库删除 DELETE FROM python_modules WHERE module_name = 'module_to_remove'; ``` ### 备份与恢复 ```bash # 数据库是单个文件,易于备份 cp modules.mbank modules.backup.mbank # 恢复 cp modules.backup.mbank modules.mbank ``` ## 📚 应用场景 1. **商业软件分发** - PyArmor 混淆保护源代码知识产权 2. **安全敏感环境** - AES 加密确保即使数据库泄露也无法还原代码 3. **插件系统** - 动态加载数据库中的加密/混淆插件模块 4. **教育平台** - 安全分发练习代码,防止学生抄袭 5. **微服务** - 打包多个服务模块到单个加密文件 6. **嵌入式系统** - 减少文件系统依赖,提高安全性 --- **注意**: 本工具主要用于模块分发和部署场景,不适合开发阶段的频繁修改。 **许可证**: MIT License