ibondarenko1/tink-cross-port-fuzz
GitHub: ibondarenko1/tink-cross-port-fuzz
针对 Google Tink 加密库多语言移植版本的差异化模糊测试工具,通过对比各实现处理相同输入的行为差异来自动发现跨端口安全漏洞。
Stars: 0 | Forks: 0
# tink-cross-port-fuzz
一个针对 [Google Tink](https://github.com/tink-crypto) 的差异化模糊测试工具,它将**相同的输入**提供给 Tink 加密库的多种语言移植版本,并报告它们在接受程度、错误类别或返回密钥形状方面的任何**差异**。
## 为什么
Tink 由 C++、Go、Java 和 Python 实现,每种加密原语都有各自独立但并行的实现。预期这四个移植版本在给定相同输入时表现出完全一致的行为——但在实际应用中它们会产生偏差:
| 移植版本 | 包含 `{"keys": "string"}` 的 JWK Set | 仅包含 `dp` 字段的 JWK Set RSA-PSS |
| --- | --- | --- |
| tink-cc | 拒绝 (`keys is not a list`) | 拒绝 (`private keys cannot be converted`) |
| tink-go | 拒绝 (`"keys" is not a list`) | 拒绝 (`private key can't be converted`) |
| tink-java | **未捕获的 `IllegalStateException`** | **静默接受为公钥** |
| tink-py | **未捕获的 `AttributeError`** | 拒绝 |
上表中的每一行都是截至 2026-04-27 HEAD 版本中真实存在的差异。它们是手工发现的。本工具将这种搜索过程自动化。
## 覆盖的攻击面(当前)
- `JwkSetConverter.toPublicKeysetHandle(jwk_set)` — JWK Set → Tink 密钥集 (RFC 7517)
- `BinaryKeysetReader.read(bytes)` — protobuf Keyset 反序列化(计划中,里程碑 2)
## 工作原理
对于每一项输入,测试工具会询问所有可用的运行器它将执行何种操作:
```
ACCEPT — keyset constructed without error
REJECT_TINK — port-recognized error (TinkError / GeneralSecurityException / etc.)
REJECT_OTHER — uncaught Python exception / Java unchecked exception (almost always a bug)
TIMEOUT — runner exceeded budget
```
当并非所有运行器达成一致时,即产生 `divergence`(差异)。最高优先级的报告行包括:
1. **来自任何移植版本的 `REJECT_OTHER`** — 未捕获的异常属于违规行为;为独立 bug
2. **来自一个移植版本的 `ACCEPT` + 来自另一个的 `REJECT_TINK`** — 语义冲突;潜在跨端口混淆攻击向量
3. **除一个以外均 `ACCEPT`** — 异常值拒绝了有效输入或接受了无效输入
## 快速开始
```
# 安装 runners (Python 是唯一必需的 port;其他为可选)
pip install -r requirements.txt
# go install ./runners/go-runner (可选)
# 在捆绑的 known-divergence corpus 上运行
python harnesses/py/differential.py corpus_jwk/
# 使用 atheris (libFuzzer engine) 进行 fuzz
python harnesses/py/atheris_jwk.py corpus_jwk/
```
每项差异将被写入 `reports/.json` 文件中,并包含完整的各移植版本运行结果。
## 状态
**里程碑 1 — 已于 2026-04-28 完成:** 针对 JWK Set 转换器的 Python 和 Go 运行器。
在 Linux + Windows 上进行了端到端验证:11/16 的种子语料库输入被标记为跨端口差异(`py:REJECT_OTHER` 对比 `go:REJECT_TINK`)。示例报告行:
```
DIVERGENCE 01_alg_int.json -> py:REJECT_OTHER (AttributeError) / go:REJECT_TINK ("alg" is not a string)
DIVERGENCE 02_x_int.json -> py:REJECT_OTHER (AttributeError) / go:REJECT_TINK ("x" is not a string)
DIVERGENCE 06_kid_int.json -> py:REJECT_OTHER (TypeError) / go:REJECT_TINK ("kid" is not a string)
DIVERGENCE 11_keys_int.json -> py:REJECT_OTHER (TypeError) / go:REJECT_TINK ("keys" is not a list)
DIVERGENCE 14_keys_array_of_int.json -> py:REJECT_OTHER (AttributeError) / go:REJECT_TINK
agree 09_no_keys.json -> py:REJECT_TINK / go:REJECT_TINK
agree 16_valid_es256_baseline.json -> py:ACCEPT / go:ACCEPT
```
仅种子语料库就与通过 Google OSS VRP 提交的 bug 类别相吻合(追踪器编号 `5332419769532416`,tink-java JwkSetConverter 移植版本回退)。
**里程碑 2 — 计划中:** 通过 `JwkSetConverter` 的子进程封装实现 Java 运行器。通过 Bazel 构建的 CLI 实现 C++ 运行器。
**里程碑 3 — 计划中:** 添加 proto Keyset 反序列化攻击面;通过 libFuzzer + atheris 进行结构化语料库挖掘。
## 许可证
Apache 2.0。Tink 本身也是 Apache 2.0;本测试工具是独立的,并且仅调用公共 API。
## 报告者
Ievgen Bondarenko ([@ibondarenko1](https://github.com/ibondarenko1))。欢迎提交 Bug 报告、PR 和差异语料库。
标签:C++, CISA项目, DevSecOps, Differential Fuzzing, Go, Google Tink, JWK, JWK Set, Python, RFC 7517, Ruby工具, 一致性验证, 上游代理, 多语言支持, 安全测试框架, 密码学测试, 差异模糊测试, 异常检测, 数据擦除, 无后门, 日志审计, 模糊测试工具, 模糊测试框架, 网络安全, 跨端口测试, 跨语言加密库, 逆向工具, 隐私保护