今日开源[第36期]croc
croc 项目分析报告
分析日期:2026-07-24
一、项目介绍
1.1 项目概述
croc 是一个简单、安全的跨计算机文件传输工具,由 Zack Schollz 开发。其核心定位是"Easily and securely send things from one computer to another"(轻松安全地在计算机之间传输文件)。它通过公共中继服务器实现任意两台计算机之间的文件传输,无需公网 IP、端口转发或复杂的网络配置。用户只需一个 3 词代码短语即可完成端到端加密传输,是 magic-wormhole 理念在 Go 生态中的成熟实现 $TRAE_REF。
1.2 项目信息
| 项目 | 详情 |
|---|---|
| 项目名称 | croc |
| 项目地址 | https://github.com/schollz/croc |
| 项目官网 | https://schollz.com/software/croc6 |
| 安装脚本 | https://getcroc.com |
| Web 客户端 | https://getcroc.com |
| 作者 | Zack Schollz(GitHub: @schollz),美国西雅图,软件工程师 + 科学家 |
| Stars | 30,384(截至 2026 年 7 月) |
| Forks | 1,215 |
| 当前版本 | v10.2.4 |
| 开源协议 | MIT License |
| 主要语言 | Go 100% |
| 创建时间 | 2017 年 10 月 17 日 |
| 提交数 | 2,257 commits |
| Open Issues | 10 |
1.3 作者简介
Zack Schollz 是一位多产的独立开发者,GitHub 拥有 3.6k 追随者,发布了 1.2k 个仓库。他的其他知名项目包括:
- howmanypeoplearearound(7.1K Stars)—— 通过 WiFi 信号监测周围人数
- find3(4.8K Stars)—— 高精度室内定位框架
- progressbar(4.7K Stars)—— Go 语言进度条库
1.4 项目示意图
README 和项目官网中提供了以下可视化资源:
- 品牌标识:croc 意为"鳄鱼(crocodile)",官网有鳄鱼图标
- 工作原理图:展示发送方 → 中继服务器 → 接收方的端到端加密传输流程
- PAKE 密钥交换流程图:展示双方通过代码短语协商会话密钥的密码学过程
- 终端运行截图:发送方显示 3 词代码短语和传输进度条,接收方显示文件接收确认
- QR 码示例:移动端扫码接收文件的功能展示
- Web 客户端界面:getcroc.com 的浏览器端接收文件界面
二、项目亮点
2.1 中继服务器架构(零配置穿透)
croc 的核心架构基于公共中继服务器,这是其实现"零配置"的关键 $TRAE_REF:
工作流程:
- 发送方和接收方都连接到同一个中继服务器(默认
croc.schollz.com:9009) - 双方通过代码短语在同一个"房间"中匹配
- 房间名由代码短语前 4 个字符 + 固定字符串 "croc" 做 SHA256 哈希生成
- 中继服务器将双方的 TCP 连接进行管道桥接(pipe),透明转发数据
- 关键安全保证:中继服务器无法解密传输内容,因为加密密钥由 PAKE 协议在两端直接协商产生
中继服务器默认使用 TCP 端口 9009-9013(1 个控制端口 + 4 个并发数据传输端口),最少需要 2 个端口。
2.2 PAKE 密码认证密钥交换(核心安全创新)
PAKE(Password-Authenticated Key Agreement)是 croc 最核心的安全机制,允许双方通过一个低熵共享密码(3 词代码短语)协商出高熵会话密钥 $TRAE_REF:
具体流程:
- 发送方生成随机 3 词代码短语(如
piano-battery-lion) - 代码短语前 4 个字符用于生成房间名,第 5 个字符之后用于 PAKE 初始化
- PAKE 使用椭圆曲线加密(默认
p256,可选p384、p521、siec) - 双方通过 PAKE 协议交换公钥后,各自派生出相同的会话密钥
- 所有文件数据使用该会话密钥进行 AES 加密传输
- 中继服务器不持有代码短语,也无法解密数据
2.3 分层加密体系
通信协议采用双层加密:
| 层级 | 加密方式 | 目的 |
|---|---|---|
| 客户端 ↔ 中继 | 弱 PAKE 密钥协商 | 保护中继信令通道,防止未授权使用中继 |
| 发送方 ↔ 接收方 | 代码短语派生的 PAKE 会话密钥 | 端到端加密,中继服务器无法解密 |
数据包格式:[MAGIC_BYTES "croc"][4 字节长度头][加密数据]
2.4 断点续传与自动重连
v10 版本引入了完善的重连机制:
- 传输中断后自动尝试重连,最多 10 次
- 使用指数退避策略(100ms 起,每步翻倍,最大 5 秒)
- 重连时生成新的重连房间名,通过
nextReconnectRoom字段传递 - 接收方记录已完成的文件块,重连后仅请求缺失的块
2.5 局域网自动直连
croc 通过 peerdiscovery 库实现局域网 UDP 多播发现(默认地址 239.255.255.250),如果双方在同一局域网内,自动切换到直连模式,绕过中继服务器,获得局域网带宽的全速传输。
2.6 便捷的辅助功能
| 功能 | 说明 |
|---|---|
| QR 码传输 | --qr 参数生成二维码,手机扫码即可接收文件 |
| Web 客户端 | 通过 getcroc.com 无需安装即可在浏览器中接收文件 |
| 管道传输 | 支持 stdin/stdout 管道:cat file | croc send 和 croc --yes code > output |
| 文本发送 | --text "hello world" 直接发送文本内容 |
| 多文件传输 | 一次发送多个文件或整个文件夹 |
| 文件夹排除 | --exclude "node_modules,.venv" 排除不需要的目录 |
| 限速控制 | --throttleUpload 限制上传带宽 |
| 代理支持 | 支持 SOCKS5 和 HTTP 代理(可配合 Tor 使用) |
| 自定义加密曲线 | --curve p521 选择更强的加密曲线 |
2.7 与同类工具的差异化优势
| 特性 | croc | magic-wormhole | rsync | scp | syncthing |
|---|---|---|---|---|---|
| 无需公网 IP | ✅ 中继 | ✅ 中继 | ❌ | ❌ | ✅ 中继+发现 |
| 端到端加密 | ✅ PAKE | ✅ PAKE | ❌ 需额外配置 | ✅ SSH | ✅ TLS |
| 断点续传 | ✅ v10+ | ❌ | ✅ | ❌ | ✅ 同步 |
| 多文件/文件夹 | ✅ | ✅ | ✅ | ✅ | ✅ 同步 |
| 跨平台 | ✅ 全平台 | Linux/macOS 为主 | Unix 为主 | Unix 为主 | ✅ 全平台 |
| 无需安装服务端 | ✅ 公共中继 | ✅ 公共中继 | 需 SSH | 需 SSH | 需安装 |
| 代码短语 | 3 个单词 | 数字+单词 | 无 | 无 | 无 |
| 局域网直连 | ✅ 自动发现 | ✅ | ✅ | ✅ | ✅ |
| 代理支持 | ✅ SOCKS5/HTTP | 有限 | SSH 隧道 | SSH 隧道 | ✅ SOCKS5 |
| Web 客户端 | ✅ getcroc.com | ❌ | ❌ | ❌ | ✅ Web UI |
| 社区规模 | 30K Stars | 21K Stars | 极成熟 | 系统自带 | 65K Stars |
croc 的核心优势在于在"零配置、极简使用"和"安全传输"之间取得了最佳平衡。用户只需 3 个单词,无需配置 IP、端口、证书或用户账户。
三、项目运行环境
3.1 基础要求
| 要求 | 说明 |
|---|---|
| Go 版本 | 从源码构建需要 Go 1.22+ |
| 磁盘空间 | 二进制文件约 10MB,无额外运行时依赖 |
| 网络 | 需要访问公共中继服务器(默认 croc.schollz.com:9009)或自建中继 |
| 端口 | 默认使用端口 9009-9013(中继模式),局域网发现使用 UDP 多播 |
3.2 操作系统支持
| 操作系统 | 安装方式 |
|---|---|
| Linux | curl 脚本 / apt / yum / dnf / pacman / nix / snap / Docker |
| macOS | Homebrew / MacPorts / curl / Conda / Docker |
| Windows | Scoop / Chocolatey / Winget / 直接下载 exe |
| FreeBSD | pkg |
| Android | Termux / F-Droid(crocgui, croc-app) |
| Alpine Linux | apk + curl |
| Arch Linux | pacman |
| Fedora | dnf |
| Gentoo | emerge |
| NixOS | configuration.nix |
3.3 安装方式
一键安装(所有平台):
curl https://getcroc.com | bash
包管理器安装:
# macOS
brew install croc
# Windows
scoop install croc
choco install croc
winget install schollz.croc
# Arch Linux
pacman -S croc
# Fedora
dnf install croc
# FreeBSD
pkg install croc
# Conda
conda install --channel conda-forge croc
Docker 安装:
croc() {
[ $# -eq 0 ] && set -- ""
mkdir -p "$HOME/.config/croc"
docker run --rm -it \
--user "$(id -u):$(id -g)" \
-v "$(pwd):/c" \
-v "$HOME/.config/croc:/.config/croc" \
-w /c \
-e CROC_SECRET \
docker.io/schollz/croc "$@"
}
从源码构建:
go install github.com/schollz/croc/v10@latest
3.4 基本使用命令
发送文件:
croc send file.txt
# 输出: Sending 'file.txt' (X MB)
# Code is: piano-battery-lion
接收文件:
croc piano-battery-lion
自定义代码短语(至少 6 个字符):
croc send --code mysecret file.txt
发送文件夹:
croc send my-folder/
发送多个文件:
croc send file1.txt file2.jpg file3.pdf
通过管道发送:
cat file.txt | croc send
croc --yes code-phrase > output.txt
发送文本:
croc send --text "hello world"
显示二维码(移动端扫码接收):
croc send --qr file.txt
使用自定义中继:
croc --relay "myrelay.example.com:9009" send file.txt
自建中继服务器:
croc relay
# 默认端口 9009-9013
排除文件夹:
croc send --exclude "node_modules,.venv" my-folder/
自动覆盖/重命名:
croc --yes --overwrite <code>
croc --yes --rename <code>
选择加密曲线:
croc --curve p521 <code>
四、项目代码介绍
4.1 代码架构图
croc/
├── main.go # 程序入口,信号处理与生命周期管理
├── go.mod / go.sum # Go 模块定义(v10, go 1.25.0)
├── Dockerfile # Docker 多阶段构建
├── .goreleaser.yml # 跨平台发布配置
├── croc-entrypoint.sh # Docker 入口脚本
├── croc.service # systemd 服务文件
│
├── web/ # React/Vite Web 客户端(getcroc.com)
│
└── src/
├── cli/ # 命令行接口层
│ └── cli.go # 所有命令定义、参数解析、send/receive/relay/serve
│
├── croc/ # 核心传输逻辑层
│ └── croc.go # Client 结构体、PAKE 协商、文件传输、重连机制
│
├── tcp/ # TCP 中继服务器
│ └── tcp.go # 中继服务器、房间管理、管道桥接(pipe)
│
├── comm/ # TCP 通信原语
│ └── comm.go # 消息帧格式、SOCKS5/HTTP 代理、超时管理
│
├── crypt/ # 加密模块
│ └── crypt.go # AES 加密/解密、密钥派生
│
├── message/ # 消息编解码
│
├── models/ # 常量与模型定义
│ └── constants.go # 默认中继地址、端口、密码、DNS 解析
│
├── compress/ # 压缩模块
├── mnemonicode/ # 代码短语生成(3 词随机短语)
├── utils/ # 工具函数
├── diskusage/ # 磁盘空间检查
├── docs/ # 文档
├── install/ # 安装辅助
├── webassets/ # Web 客户端静态资源
└── webrelay/ # WebSocket 中继
4.2 系统架构
┌──────────────────────────────────────────────────────┐
│ 用户交互层 │
│ CLI (send/receive) │ Web 客户端 │ Android App │
└──────────────────┬───────────────────────────────────┘
│
┌──────────────────┴───────────────────────────────────┐
│ CLI 命令层 (cli.go) │
│ send │ receive │ relay │ serve │ 自动判断模式 │
└──────────────────┬───────────────────────────────────┘
│
┌──────────────────┴───────────────────────────────────┐
│ 核心传输层 (croc.go) │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │PAKE 协商 │ │文件传输 │ │ 重连机制 │ │
│ │(p256等) │ │(分块+多路)│ │ (10次指数退避) │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└──────────────────┬───────────────────────────────────┘
│
┌──────────────────┴───────────────────────────────────┐
│ 通信与加密层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │TCP 传输 │ │加密/解密 │ │ 压缩/解压 │ │
│ │(comm.go) │ │(crypt.go) │ │ (compress) │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└──────────────────┬───────────────────────────────────┘
│
┌──────────────────┴───────────────────────────────────┐
│ 中继服务器层 (tcp.go) │
│ 房间管理 │ 弱 PAKE 认证 │ 管道桥接 │ 定时清理 │
└──────────────────────────────────────────────────────┘
4.3 核心模块介绍
| 模块 | 路径 | 功能 |
|---|---|---|
| 程序入口 | main.go |
信号处理、优雅退出、临时文件清理 |
| CLI 命令层 | src/cli/cli.go |
定义 send/receive/relay/serve 四个子命令,自动判断模式 |
| 核心传输 | src/croc/croc.go |
Client 结构体管理整个传输生命周期:PAKE 协商、文件信息交换、分块传输、重连 |
| TCP 中继 | src/tcp/tcp.go |
中继服务器核心:房间管理、弱 PAKE 认证、管道桥接、房间清理 |
| 通信协议 | src/comm/comm.go |
自定义消息帧格式、代理支持、超时管理 |
| 加密模块 | src/crypt/crypt.go |
AES 加密/解密、密钥派生 |
| 压缩模块 | src/compress/ |
传输前压缩、接收后解压 |
| 消息编解码 | src/message/ |
结构体与字节流的序列化/反序列化 |
| 代码短语 | src/mnemonicode/ |
随机 3 词代码短语生成 |
| Web 中继 | src/webrelay/ |
WebSocket 中继支持(用于 Web 客户端) |
4.4 核心代码解析
4.4.1 中继服务器管道桥接(tcp.go)
这是中继服务器最核心的逻辑——将两个客户端的 TCP 连接进行双向管道桥接:
// pipe 函数:双向管道桥接,透明转发数据
func pipe(conn1 net.Conn, conn2 net.Conn) {
chan1 := chanFromConn(conn1)
chan2 := chanFromConn(conn2)
for {
select {
case b1 := <-chan1:
if b1 == nil {
return
}
conn2.Write(b1)
case b2 := <-chan2:
if b2 == nil {
return
}
conn1.Write(b2)
}
}
}
中继服务器的工作流程:
- 客户端连接 → 使用弱 PAKE 建立加密通道
- 密码验证 → 客户端发送加密的中继密码
- 房间分配 → 客户端指定房间名,服务器创建或加入房间
- 管道桥接 → 当房间内有两个客户端时,通过
pipe()建立双向数据管道 - 房间清理 → 定时清理超时房间
4.4.2 PAKE 密钥协商(croc.go)
// 发送方初始化 PAKE
c.Pake, err = pake.InitCurve(
[]byte(c.Options.SharedSecret[5:]), // 代码短语第5个字符之后
0, // 角色 0 = 发送方
c.Options.Curve, // 椭圆曲线(默认 p256)
)
// 中继服务器使用弱密钥进行 PAKE
// 中继密码默认 "pass123",因此中继的 PAKE 是弱安全的
B, err := pake.InitCurve(weakKey, 1, "siec")
关键设计:
- 代码短语前 4 个字符用于生成房间名(通过 SHA256 哈希)
- 代码短语第 5 个字符之后用于 PAKE 初始化
- 中继服务器使用弱密钥的 PAKE 仅用于防止未授权使用,不依赖它保护数据
4.4.3 通信协议帧格式(comm.go)
// 自定义消息帧格式
// [MAGIC_BYTES "croc" (4字节)] [长度头 (4字节 LittleEndian)] [数据体]
//
// 最大消息大小:64MB
// 读超时:3小时(长连接场景)
// 写超时:3小时
// 支持 SOCKS5 和 HTTP 代理
// TCP 连接建立时自动检测代理配置
4.4.4 加密模块(crypt.go)
// 密钥派生:从强密钥生成加密密钥和盐
func New(strongKey []byte, salt []byte) (key []byte, newSalt []byte, err error)
// AES 加密:使用派生密钥加密数据
func Encrypt(data []byte, key []byte) ([]byte, error)
// AES 解密:使用派生密钥解密数据
func Decrypt(data []byte, key []byte) ([]byte, error)
分层加密体系:
- 客户端 ↔ 中继:弱 PAKE 密钥协商(中继密码
pass123),仅保护信令通道 - 发送方 ↔ 接收方:代码短语 PAKE 密钥协商,端到端加密,中继不可解密
4.4.5 重连机制(croc.go)
const (
ReconnectVersion = 1
maxReconnectAttempts = 10 // 最多重连 10 次
)
// transferWithReconnect() 实现:
// 1. 传输中断后自动尝试重连
// 2. 指数退避策略:100ms 起,每步翻倍,最大 5 秒
// 3. 重连时生成新的重连房间名(nextReconnectRoom)
// 4. 接收方记录已完成的文件块,重连后仅请求缺失的块
// 5. 双方都需要 ReconnectVersion >= 1 才支持此功能
4.4.6 关键依赖库
| 依赖 | 用途 |
|---|---|
schollz/pake/v3 |
PAKE 密钥协商协议实现 |
schollz/peerdiscovery |
局域网 UDP 多播发现 |
schollz/progressbar/v3 |
终端进度条显示 |
schollz/logger |
日志框架 |
schollz/cli/v2 |
CLI 框架 |
coder/websocket |
WebSocket 支持(Web 客户端) |
golang.org/x/crypto |
加密原语 |
golang.org/x/term |
终端处理 |
skip2/go-qrcode |
二维码生成 |
kalafut/imohash |
快速文件哈希 |
cespare/xxhash/v2 |
xxHash 快速哈希 |
sabhiram/go-gitignore |
.gitignore 规则解析 |
denisbrodbeck/machineid |
机器唯一标识 |
五、项目应用与评价
5.1 应用场景
| 场景 | 说明 |
|---|---|
| 临时文件分享 | 两台电脑之间快速发送文件,无需上传到云盘,无需注册账号 |
| 跨网络传输 | 不同 NAT 后的设备互相传输(如公司内网和家庭网络之间) |
| 向非技术用户发送文件 | 接收方只需运行一个命令加 3 词代码短语,零学习成本 |
| 服务器间文件传输 | 无需配置 SSH 密钥或 FTP 服务,一行命令完成传输 |
| 移动端接收文件 | 通过 --qr 生成二维码,手机扫码即可接收电脑发来的文件 |
| 企业内网自建中继 | 部署私有中继服务器,完全掌控数据传输路径,保障敏感文件安全 |
| 脚本自动化 | 通过管道和 --yes 参数实现无人值守的文件传输 |
| 远程协作 | 跨地域团队快速共享代码、文档、数据集等 |
5.2 项目优点
- 极简使用:一行命令发送,一行命令接收,3 词代码短语匹配,无需任何配置。
- 安全保障:端到端加密(PAKE),中继服务器无法窃取数据,代码短语不在网络上明文传输。
- 零配置穿透:不需要公网 IP、端口转发、DNS 配置、防火墙规则修改。
- 跨平台完整:从 Windows、macOS、Linux 到 Android、FreeBSD 全覆盖。
- 断点续传:v10 版本支持传输中断后自动恢复,最多 10 次重连,指数退避。
- 局域网优化:自动检测并直连局域网内的对端,绕过中继获得全速传输。
- 丰富的功能选项:限速、排除文件、代理、自定义加密曲线、QR 码、管道传输等。
- Web 客户端:通过
getcroc.com无需安装即可在浏览器中接收文件。 - 自建中继:可完全掌控数据传输路径,企业内网部署私有中继保障安全。
- 活跃维护:2,257 次提交,30K Stars,截至 2026 年 7 月仍在活跃开发,仅 10 个 Open Issues。
5.3 项目不足
- 依赖公共中继:默认依赖作者的公共中继服务器,可能存在单点故障风险。虽然可以自建中继,但需要额外运维。
- 中继密码薄弱:默认中继密码为
pass123,中继的 PAKE 基于已知弱密钥,理论上可能被攻击者使用中继服务。 - 传输速度受限于中继:非局域网场景下,数据通过中继转发,速度受中继服务器带宽限制。
- 非实时同步:与 syncthing 不同,croc 是点对点一次性传输,不支持持续同步或增量同步。
- 无原生桌面 GUI:CLI 工具为主,虽然有 Web 客户端和 Android 应用,但无原生桌面 GUI。
- 大文件增量传输缺失:虽支持断点续传,但无增量传输/差量同步能力,修改大文件后需重新传输整个文件。
- 端口需求多:默认需要 5 个端口(1 控制 + 4 传输),在严格防火墙环境下配置较复杂。
- 经典模式安全风险:
--classic模式在命令行中暴露代码短语(CVE-2023-43621),Linux/macOS 上默认使用环境变量方式避免此问题,但 Windows 上仍存在风险。

浙公网安备 33010602011771号