From 0034abca9cebcb8d431c6fb7acf0ccb56dff1257 Mon Sep 17 00:00:00 2001 From: lou Date: Mon, 10 Aug 2026 02:15:14 +0800 Subject: [PATCH] =?UTF-8?q?README:=20=E9=A1=B9=E7=9B=AE=E4=BB=8B=E7=BB=8D?= =?UTF-8?q?=20+=209=20=E5=A4=A7=E7=89=B9=E8=89=B2=20+=20=E7=99=BE=E5=BA=A6?= =?UTF-8?q?=E7=BD=91=E7=9B=98=E5=AF=B9=E6=AF=94=E8=A1=A8=20+=20=E5=BF=AB?= =?UTF-8?q?=E9=80=9F=E5=BC=80=E5=A7=8B/=E5=8D=8F=E8=AE=AE/=E6=8A=80?= =?UTF-8?q?=E6=9C=AF=E6=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e685316 --- /dev/null +++ b/README.md @@ -0,0 +1,185 @@ +# 7z-encrypt 文件安全传输系统 + +端到端加密 + 最高压缩 + 分卷传输的私有文件网盘。自托管、零知识、零合并——服务器只存密文卷,既看不到内容,也看不到文件名。 + +``` +本地 服务器 (你自有的任何机器) 本地 +文件 ──7z -mx=9 压缩──> ┌───────────────────────┐ ──逐卷下载──> 密文 + │ │ 只存密文卷, 不合并 │ │ + ├─ cobblestone 加密 ─>│ 不持密钥, 不解密 │ ├─ 解密 + ├─ 分卷 + SHA-256 ───>│ 不存明文文件名 │ ├─ 7z 解压 + └─ 分片上传(Bearer) ─>│ SQLite 元数据 │ └─ 还原原文件 + └───────────────────────┘ +``` + +- **传输协议**: HTTPS + REST 分片上传(卷 = 分片,失败只重传该卷) +- **加密**: cryptography.cobblestone(C2SP chunked AES-256-GCM,16KiB 块级流式 + 块级认证) +- **压缩**: 7z -mx=9 最高压缩(文本类文件实测 95% 压缩率,传输量大幅下降) +- **架构**: 客户端 / 服务端 / TUI 三项目解耦,客户端只依赖共享 protocol 契约 + +--- + +## 特色 + +### 1. 零知识 — 服务器没有密钥 + +服务端不持有任何密钥材料,不解密、不碰明文。密文卷上传 → 密文卷存储 → 密文卷下载,客户端本地完成全部解密。 + +``` +服务端被攻破 / 管理员偷看 / 服务器被扣押 → 手里只有密文 +文件内容 + 密钥都在你手里, 数据安全不依赖服务器可信度 +``` + +### 2. 零合并 — 服务器不做任何合并操作 + +上传的卷直接落盘(`chunk_0001..N`),complete 只校验卷齐 + 目录 move 入库,**秒回**。下载时客户端逐卷拉取、本地拼接。 + +``` +传统方案: 上传 100% → 等服务端合并大文件 (2G 要几分钟) +本方案: 上传 100% → 秒回 done (6 卷实测全流程 1.1 秒) +服务端 CPU 几乎为零: 收卷存卷、发卷, 纯 IO 转发 +``` + +### 3. 元数据零知识 — 文件名也加密 + +文件名用独立 context 加密成 URL-safe base64(`enc:` 前缀),服务器只见密文。客户端 ls / 下载时本地解密还原原名。 + +``` +服务端能看到: 密文文件名 / 大小 / 卷数 / 卷哈希 (完整性校验用) +服务端看不到: 明文文件名 / 文件内容 +``` + +### 4. 压缩 → 加密 → 分卷 → 上传 管线 + +``` +源文件 → 7z -mx=9 → .7z → cobblestone 加密 → 密文 → 分卷 → 逐卷上传 +下载反向: 逐卷拉取 → 本地拼接密文 → 解密 → 7z 解压 → 原文件 +``` + +先压缩再加密(密文不可压缩,顺序反了压缩率归零)。文本实测 3.8MB → 0.2MB,传输量省 95%。 + +### 5. 卷粒度断点续传 + +每卷独立 PUT + 独立 SHA-256 校验。中断后 `GET /chunks` 查已收卷,只补传缺失卷,天然续传。 + +### 6. 认证 + 配额 + 文件管理 + +- Bearer token 认证(预共享,无/错 token 一律 401) +- 空间配额查询(已用 / 配额 / 剩余 / 百分比) +- ls / 下载 / 删除全套文件管理 +- 下载按卷粒度进度显示,与上传日志对称 + +### 7. 全面进度可视化 (tqdm) + +上传卷条、下载双层嵌套条(外层卷 / 内层字节)、加密条、分卷条、解密条——所有耗时操作都有实时进度,拒绝黑盒等待。 + +### 8. 轻量部署 — SQLite + 标准库优先 + +服务端 Python 标准库 + FastAPI,数据库 SQLite(零进程零安装)。PRoot 容器(手机 ZeroTermux)、树莓派、任何 VPS 都能跑。 + +### 9. 输入安全加固 + +- 下载文件名消毒(basename,防路径穿越) +- init json 大小限制 1MB / 卷数上限 10000 / 文件名清洗 +- 所有 SQL 参数化,token 不落库 + +--- + +## 与百度网盘对比 + +| 维度 | 百度网盘 | 7z-encrypt | +|---|---|---| +| **数据安全** | 服务器持有明文,可扫描/审查/和谐;VIP 可享"原画"也意味着服务器能看 | 端到端零知识:服务器只有密文,无密钥无法解密,内容+文件名双重加密 | +| **速度** | 非会员限速 ~100KB/s,会员才跑满 | 自己服务器的带宽,不限速;7z 压缩省 95% 传输量 | +| **空间** | 免费 2TB 但限速/限单文件大小,扩容要付费 | 服务器磁盘即空间,配额自定(环境变量 SZ_QUOTA) | +| **费用** | 会员 30+/月,续费永无止境 | 自托管零月费,一台旧手机/小 VPS 即可 | +| **隐私** | 内容会被 AI 扫描、分享链接可被举报和谐 | 零知识架构,服务器管理员都看不到内容 | +| **审查** | 敏感内容秒和谐,资源类文件风险高 | 无审查无和谐,纯私有传输 | +| **广告** | 客户端广告、推广位、全家桶 | 无广告,无推广 | +| **文件操作** | 上传/下载受客户端控制,断点续传要会员 | 卷粒度断点续传免费,上传失败只重传缺失卷 | +| **可控性** | 关停风险、政策风险、客户端强制更新 | 完全自托管,代码开源,随时审计 | +| **部署** | 不可自部署 | 单文件服务端,SQLite,手机容器都能跑 | +| **扩展** | 生态封闭,API 受限 | REST API 全开放,可编程上传/下载 | +| **成本对照** | 100GB 文件传一年会员费 ≈ 400 元 | 0 元软件成本 + 自己的服务器电费 | + +**一句话**: 百度网盘是"存给百度看的网盘",7z-encrypt 是"只存密文的管道"——前者买的是空间,后者买的是隐私和速度。 + +--- + +## 快速开始 + +```bash +# 1. 服务端 (任何有 Python 3.11+ 的机器) +cd server +pip install fastapi uvicorn cryptography tqdm +SZ_TOKEN=你的token python3 main.py # 默认 0.0.0.0:8000 + +# 2. 客户端 +cd 7z-encrypt +uv pip install --python .venv/bin/python tqdm +python config.py --init +python config.py --set-server http://服务器IP:8000 +python config.py --set-token 你的token + +# 3. TUI (推荐) +python3 ../tui/scripts/tui.py +# 菜单: 1上传 / 2任务续传 / 3配置 / 4文件列表 / 5下载 / 6删除 / q退出 +``` + +## 测试 + +```bash +cd 7z-encrypt && .venv/bin/pytest -q # 70 项 +cd server && .venv/bin/pytest -q # 9 项 +``` + +覆盖:加密/解密回环、7z 压缩回环、逐卷上传下载、断点续传、token 认证、文件名加密回环、路径穿越防护、配额、幂等、坏卷拒绝、超大清单拒绝。 + +--- + +## 目录结构 + +``` +7z-encrypt/ 客户端 (标准库优先) + ├─ file_reader.py 流式读取 + ├─ crypto.py 加密/解密/文件名加密 (cobblestone AES-256-GCM) + ├─ splitter.py 分卷 + SHA-256 + ├─ metadata.py 元数据 (init json / 卷清单) + ├─ transfer.py HTTP 传输 (上传/下载/删除/配额, Bearer 认证) + ├─ state.py 断点状态 + ├─ config.py 配置 (server/token/keyring) + └─ tests/ 70 项测试 + +server/ 服务端 (FastAPI + SQLite, 零知识零合并) + ├─ api.py REST 端点 (认证/传输/文件/配额) + ├─ receiver.py 卷接收 + 哈希校验 + ├─ storage.py 卷目录存储 (move 入库, 不合并) + ├─ db.py SQLite (transfers/files/chunks) + ├─ task_manager.py 任务状态机 + 输入清洗 + └─ tests/ 9 项测试 + +tui/ 终端界面 + └─ scripts/tui.py Python TUI (input() REPL, 原生支持中文输入法) +``` + +## 协议一览 + +``` +POST /api/transfer/init 建任务 {transfer_id} +PUT /api/transfer/{id}/chunk/{n} 上传单卷密文 409 = 坏卷 +GET /api/transfer/{id}/chunks 已收卷列表 断点续传 +POST /api/transfer/{id}/complete 卷齐入库(秒回) {file_id} +GET /api/files 文件列表 文件名是加密的 +GET /api/files/{id}/chunk/{n} 下载单卷密文 X-Enc-Params 头带解密参数 +DELETE /api/files/{id} 删除文件 +GET /api/quota 空间配额 +全部端点需 Authorization: Bearer +``` + +## 技术栈 + +- Python 3.11+ / FastAPI / uvicorn / SQLite +- cryptography 50 (cobblestone C2SP chunked AES-256-GCM) +- 7z (p7zip, -mx=9) +- tqdm 进度条 +- 测试: pytest (真实行为测试, 无 mock)