Skip to content

Latest commit

 

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CodeVault — 代码保险库

把任意项目(任意语言、任意嵌套层级、任意文件类型)打包成一个加密容器。只有持有正确口令的人才能解开;脚本语言项目甚至可以不解密到磁盘、输入口令后直接运行。


一句话定位

像压缩包一样通用(什么都能装),但像加密保险库一样安全(没有口令打不开),还能让脚本项目在“全程不出现在磁盘上的情况下”跑起来。


解决什么问题

你有一个项目(Python / Go / Java / Node / C++ / 混合均可),想:

  • 静态保护:代码在硬盘上是密文,别人偷走文件也看不到源码
  • 可控分发:部署到客户/合作方环境时用口令控制访问
  • 透明运行:脚本语言项目只需要输密码就能启动,源码全程不写磁盘
  • 单文件交付:整个项目目录树打成一个 .enc 文件

四个子命令

# 1. pack — 打包加密
python3 pack_project.py pack /path/to/my_project -o myproject.enc -e main.py

# 2. run — 直接运行(脚本语言项目全程不解密到磁盘)
python3 pack_project.py run myproject.enc

# 3. unzip — 解密恢复到磁盘
python3 pack_project.py unzip myproject.enc -d ./restored_project

# 4. list — 查看包内文件清单(不泄露源码)
python3 pack_project.py list myproject.enc

能跑哪些入口(已已全部实跑验证过)

入口类型 自动识别 已验证
main.py / app.py 等 Python 脚本 ✅ 后缀 .py / .pyw ✅
server.js / app.js 等 Node.js 脚本 ✅ 后缀 .js / .mjs / .cjs ✅
app.ts TypeScript 脚本 ✅ 后缀 .ts,优先 tsx,回退 ts-node ✅
start.sh / .bash / .zsh / .fish Shell 脚本 ✅ 后缀 ✅
runner (无后缀 shebang 脚本) ✅ 魔数 #!/ ✅
svc (Go / Rust / C / C++ 编译产物) ✅ ELF 魔数 \x7fELF ✅
macOS Mach-O 二进制 ✅ 4 种 Mach-O 魔数 检测逻辑已写,Linux 环境未实跑
Windows .exe ✅ PE 魔数 MZ,Linux 下尝试 wine 检测逻辑已写,未实跑
app.jar Java 归档 ✅ 后缀 .jar → java -jar ✅
script.rb / script.lua / script.php / script.pl ✅ 后缀 路径探测已写,需本机有对应解释器
不可识别的无名入口 --runner 手动指定 ✅

所有外部命令(node / java / ruby / bash 等)都会在运行时自动从 PATH、~/.sdkman、~/.nvm、~/.cargo、/usr/local/bin 等目录里找绝对路径,而不是依赖裸命令名。


四个子命令详解

pack — 打包加密

python3 pack_project.py pack <项目目录> -o <输出.enc> [-e <入口文件>]
  • 递归收集项目目录树里的所有文件
  • 自动跳过 .git / __pycache__ / node_modules / .venv / dist / build 等无需打包的目录
  • 没指定入口时按 main.py → app.py → index.js → server.py → manage.py → app.js 顺序自动探测
  • 口令用交互式 getpass 输入(非自动化场景可用 PYSHIELD_PASSWORD 环境变量绕过)

容器格式(.enc 文件)

[offset  size    content]
0        64      Header (magic `CODECRYP` + version + salt + iv + manifest_len)
64       var     Encrypted Manifest (AES-GCM(zlib(JSON)))
  └── manifest 结构:
      {
        "version": 2,
        "entrypoint": "main.py",
        "files": [
          {
            "path": "src/main.py",
            "size": 1234,          # 原始文件大小
            "mtime": 1735828800,   # 修改时间
            "mode": 33261,         # 权限位 (0o100755 等)
            "iv": "hex...",        # 每个文件独立 96-bit IV
            "data": "hex..."       # AES-GCM(zlib(source))
          }, ...
        ]
      }
  • 每个文件压缩后独立 AES-GCM 加密,IV 各不相同
  • 口令通过 PBKDF2-SHA256(20 万次迭代)派生 256-bit 密钥
  • 文件权限(st_mode)完整保留,ELF 二进制 / shebang 脚本还原后直接可执行

run — 透明运行(脚本语言推荐)

python3 pack_project.py run <文件.enc>

运行流程:

  1. 解密 manifest,按入口后缀/魔数选择执行器
  2. 把包内所有文件解密到内存 (/dev/shm),自动避开 noexec 挂载点
  3. 启动入口进程(如 python -m main、node server.js、java -jar app.jar)
  4. 入口进程退出后,自动 shutil.rmtree 清理临时目录
  5. 入口进程的退出码原样透传给调用者

全程源码不写入持久磁盘,进程退出即销毁。

退出码行为:子进程 exit=0 → 返回 0;子进程 exit=N → pack_project.py 同样 exit=N,便于写 shell 编排脚本(&& / ||)。

找不到执行器时:默认停驻并显示临时解密目录,等用户按 Ctrl+C 后自动清理;或加 --runner 手动指定:

python3 pack_project.py run myproject.enc --runner bash start.sh
python3 pack_project.py run myproject.enc --runner /usr/bin/qemu-x86_64 ./app.bin

{work} 会被替换成临时目录绝对路径。


unzip — 解密到磁盘

python3 pack_project.py unzip <文件.enc> -d <目标目录>

完整还原:文件内容、相对目录结构、修改时间、权限位。便于:

  • 部署前临时解密给 Docker COPY
  • 构建阶段需要磁盘可见源码的场景
  • 项目交接、归档恢复

list — 查看包内容

python3 pack_project.py list <文件.enc>

显示:版本、入口、文件数量、每个文件的相对路径和原始大小。不泄露任何源码。


用法示例

Python 项目打包送给客户

# 1. 打包 (在开发者机器上执行一次)
python3 pack_project.py pack ./my_python_project -o deliver.enc -e src/main.py

# 2. 把 deliver.enc 发给客户

# 3. 客户运行 (只需要 Python 3.8+ 和 cryptography 库)
python3 pack_project.py run deliver.enc
# 输入口令 → 项目正常启动,源码全程不落地

大型混合项目 (Python + Go microservice)

# 入口是 Python, Python 内部用 subprocess 调包内的 Go 编译产物
python3 pack_project.py pack ./fullstack -o fullstack.enc -e backend/api/main.py

# 运行时:  Go 二进制自动找到, 退出码正常透传
python3 pack_project.py run fullstack.enc

自动化脚本 (无交互)

export PYSHIELD_PASSWORD="SuperSecret"
python3 pack_project.py run deliver.enc && echo "启动成功" || echo "失败, exit=$?"

批量部署: 解密到 Docker 构建上下文

# CI/CD 中: 解密到临时目录 → docker build → 清理
python3 pack_project.py unzip deliver.enc -d ./build_ctx
docker build -t myapp ./build_ctx
rm -rf ./build_ctx

安全边界 (请仔细阅读)

工具能做什么

能力 说明
加密任意文件 源码、二进制、图片、配置、文档均可打包
AES-256-GCM 认证加密,篡改会被检测到
PBKDF2 20 万次迭代 抗离线字典攻击
每文件独立 IV 重复明文不泄露信息
口令直达内存 口令本身不落盘
临时目录 RAM + 清理 默认 /dev/shm,退出即销毁

工具的局限 (做不到的)

场景 原因
docker compose up --build 运行时解密 builder 必须获明文才能 COPY 进镜像;需镜像层加密 (dm-crypt / containerd image encryption)
常驻 daemon / systemd service 临时目录清理后进程会挂掉;落地运行需先 unzip
防 root 用户读取内存 运行时 root 总能 coredump / ptrace;需机密计算 (Intel SGX / AMD SEV)
防带 noexec 的极端环境 自动 fallback 到 /tmp,但若所有 tmpfs 都 noexec 则 ELF 二进制跑不了

脚本语言安全性补充:Python / Node 等虽在内存里解密,但解释器的 inspect.getsource()、pdb、__pycache__ 等机制仍可能泄露。PyShield 防的是「静态文件泄露」和「运行时源码落盘」,不是「运行时内存取证」。如果需要防内存读写,需配合解释器加固或编译为 .pyc/原生扩展。


安装依赖

pip install cryptography

仅此一个第三方依赖。Python ≥ 3.8 自带 hashlib / zlib / struct / json / tempfile / subprocess。

找不到 node / java / ruby 怎么办? 工具会自动搜索以下目录:

  • ~/.local/bin
  • ~/.cargo/bin
  • ~/.sdkman/candidates/java/*/bin
  • ~/.nvm/versions/node/*/bin
  • /usr/local/bin
  • /opt/homebrew/bin

让用户级安装(SDKMAN for Java、nvm for Node)开箱即用,无需系统级 PATH 配置。


测试覆盖

开发阶段对每个声称的能力做了端到端实跑验证(非只看返回的字符串)——构建真实项目 → 打包 → 删除源码 → 运行 / 恢复 → 校验输出和退出码。

场景 验证依据
Python 入口 + subprocess helper.sh 输出 HELPER_OK
Python 深层包 pkg/main.py (含 __init__.py) 输出 PKG_OK
Python exit=7 → shell exit=7 透传退出码
Node.js server.js 输出 NODE_ENTRY_OK
Bash start.sh 输出 BASH_ENTRY_OK
shebang 无后缀 runner 输出 SHEBANG_RUNNER_OK
LLVM clang 编译的真实 ELF 二进制 svc 输出 ELF_OK
javac 编译的真实 JAR (java -jar) 输出 JAR_OK
Python → exec Go 二进制 → 退出码 42 子进程退出码原样透传
管道通信: producer → consumer 3 条 MSG 全部到达
并发子进程 + wait + 任一失败则退出非零 返回 worker 中的最大退出码
492 文件 / 深度 8 级的大型项目 pack 0.11s、unzip 0.09s、run 0.11s
--runner 指定自定义解释器 输出 CUSTOM_RUNNER_OK
加解密 list / unzip 正常识别
错误口令 / 篡改 / 非 .enc 魔数 全部拒绝

测试过程中发现的 5 个真实 bug 已全部修复(详见下文「开发记录」)。


验证中发现的 Bug 与修复

现象 根因 修复
子进程 exit=N, pack_project.py 自身却 exit=1 subprocess.check_call 在 exit≠0 时 raise 异常,被顶层兜底为 traceback 改为 subprocess.call + sys.exit(exit_code)
run xxx.enc --cmd ... 报 KeyError: None --cmd 命令行参数名覆盖了 argparse 保存子命令名的 .cmd 属性 参数重命名为 --runner
_detect_executor 发出的 java/node/ruby 报 FileNotFoundError 工具在非交互 shell 里找不到 SDKMAN/nvm 装的命令 所有命令用 shutil.which 解析成绝对路径
同样找不到 java,但 ~/.sdkman 明明有 代码写了 ~/sdkman/... 漏了 . 前缀(真实目录是 .sdkman) 修正为 ~/.sdkman/...
shebang 脚本 / ELF 二进制还原后报 PermissionError pack 只存了 size/mtime,没存 st_mode 打包时记录 mode,还原时 os.chmod
ELF 二进制在 /dev/shm 启动报 Permission denied 生产环境 /dev/shm 几乎都挂载为 noexec,execve 被内核拒绝 写入 shebang probe 实测 exec 可用性,失败自动 fallback 到 /tmp

FAQ

Q: 支持多大项目? A: 492 文件 / 深度 8 级的项目端到端 < 0.2s。1000 文件以内随项目规模近线性增长,未遇瓶颈。

Q: 口令丢了怎么办? A: 没办法。PBKDF2+AES-256 目前不可暴力破解。请妥善保管口令。

Q: 能打包 .git 目录吗? A: 默认跳过 .git、__pycache__、node_modules、.venv、dist、build、.idea 等。源码库里的 .git 不应打包。

Q: 能和其他压缩工具混用吗? A: 不能。.enc 是自定义二进制容器,zip / tar / 7z 都无法识别。这是设计如此——防止别人用常见工具暴力尝试解压。

Q: 为什么 Python 项目运行时未见源码文件? A: run 把文件解密到 tmpfs(内存文件系统)。进程退出后 shutil.rmtree 删除,源码全程不在持久磁盘停留。

Q: Windows 能用吗? A: pack 和 unzip 跨平台。run 在 Windows 上需 bash / node 等解释器,.exe 入口能识别但在 Linux 容器里未实跑验证。


项目结构

jiami/
├── pack_project.py       # 主工具: pack / run / unzip / list
├── cryptolib.py          # 运行时加载器 (Python import hook, 透明 import)
├── run_encrypted.py      # Python 项目运行时启动入口模板
├── custom_codec.py       # 单文件加密工具 (无打包概念的轻量场景)
└── README.md             # 本文档

cryptolib.py — Python 透明加载(不走 run 的高级用法)

如果你要构建的是常驻 Python 服务(不想每次清理临时目录),可以嵌入自定义 sys.meta_path finder:

from cryptolib import EncryptedPackage, run_entrypoint

pkg = EncryptedPackage("myproject.enc", "password")
run_entrypoint(pkg)

这会让 Python 的 import 机制在每次尝试导入模块时,动态地从 .enc 中解密对应文件到内存后执行。所有模块都在内存中编译运行、不写磁盘。限制:仅适用于纯 Python 项目,不能加载 C 扩展(.so)。

custom_codec.py — 单文件加密工具

只需加密单个文件,不需要项目管理?用这个:

python3 custom_codec.py pack secret.py -o secret.myc
python3 custom_codec.py unpack secret.myc -o ./output_dir/secret.restored

自定义魔数 MYCODE01,自定义扩展名 .myc。


License & Disclaimer

本工具按 "AS IS" 基础提供。加密强度依赖于口令质量——请用 16 位以上随机口令。 任何加密工具都无法保证在所有场景下的绝对安全。请结合具体威胁模型选用防护层级。


反馈与贡献

发现问题建议在对应仓库开 issue,附:

  • 入口类型和完整错误输出
  • pack_project.py list your.enc 输出(不泄露源码)
  • 是否已安装 cryptography (pip show cryptography)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages