the-sarge/cpace
GitHub: the-sarge/cpace
CPace draft-21 Ristretto255/SHA-512 的 Go 语言实现,提供基于共享密码的平衡型认证密钥交换协议,目前处于可审计草案阶段,尚未达到生产就绪。
Stars: 0 | Forks: 0
# Go 语言的 CPace 实现
[](https://scorecard.dev/viewer/?uri=github.com/the-sarge/cpace)
[](https://www.bestpractices.dev/projects/12767)
本仓库仅针对 `CPACE-RISTR255-SHA512` 密码套件实现了 `draft-irtf-cfrg-cpace-21`。
状态:可审计的草案实现。此代码未经独立的密码学审查,尚未达到生产就绪状态。
当前的工作重点是为发布做准备,而不是设计新的策略。除非有新的发现推翻了之前的决定,否则公共 API 和包级别的配置选择已冻结以供审查。在声称具备生产就绪能力之前,必须满足 `docs/security-assessment.md` 中规定的发布标准。
公共 API 仅暴露了带有强制显式密钥确认的发起方-响应方流程:
1. `Start` 返回发起方状态和消息 A。
2. `Respond` 消费消息 A,并返回响应方状态和消息 B。
3. `Initiator.Finish` 验证消息 B,并返回消息 C 以及 `Session`。
4. `Responder.Finish` 验证消息 C,并返回 `Session`。
`Respond` 返回成功并不代表认证完成。只有成功的 `Initiator.Finish` 和 `Responder.Finish` 调用才会返回已认证的会话。
在完成调用结束之前,请将消息 B 视为未经认证的协议消息。
本模块是在 draft-21 基础上构建的特定包的 `cpace-go` 配置。它根据草案版本、密码套件、角色、发起方 ID、响应方 ID 和调用方上下文在内部构建 CI。它还拥有自己的二进制线路帧格式;应用程序应将消息字节视为不透明的,并由本模块进行版本控制。当前线路格式的前缀字节为 `0xc1`。
通信双方必须配置相同的角色方向:在两台机器上,`InitiatorID` 是调用 `Start` 的一方,而 `ResponderID` 是调用 `Respond` 的一方。一个常见的集成错误是双方都把自己的身份放在前面;这会导致 CI 输入不同,从而导致确认失败。不要为所有用户或部署仅使用全局硬编码的角色标签(例如 `"client"` 和 `"server"`)。请将稳定的、具有应用实际意义的参与方身份绑定到这些字段中。
为每个会话提供一个双方协商一致的、全新的、非秘密的 `SessionID`。默认情况下会拒绝空的会话 ID,因为它们会削弱重放和记录分离特性;该失败会包装 `ErrInvalidInput` 和 `ErrEmptySessionID` 两个错误。`AllowEmptySessionID` 的存在仅用于 draft-21 兼容性测试,或用于接受较弱空 sid 行为的特意兼容的配置。如果外部协议协商了 PAKE 版本、密码套件或是否使用 CPace,则该协商需要自己的降级保护;本包不对它从未见过的协商进行认证。有关外部协商和降级保护的指导,请参阅 `docs/integration-guidance.md`。
`Initiator.Finish` 和 `Responder.Finish` 是一次性调用。传递格式错误或确认失败的消息会消耗掉状态,并需要重新启动交换。
`Session.TranscriptID` 是已确认的 CPace 记录的草案 `CPaceSidOutput`,而不是外部协议协商的完整通道绑定。
`Session.Export` 从已确认的 ISK 中派生出确定性的、域分离的应用密钥材料。它不是新鲜随机性的来源;请为每个导出的密钥用途使用特定的标签和上下文。`Session.Close` 尽最大努力清理会话密钥材料,并使后续的 `Export` 调用因 `ErrSessionClosed` 而失败;非秘密的元数据访问器在关闭后仍可使用。`Session.PeerAssociatedData` 返回绑定到已确认交换中的对等方 AD 的确切值。`Session.PeerID` 返回由调用方配置并绑定到 CI 中、且经由交换确认的对等方身份;它不是从对等方控制的线路数据中解析出来的。
标量随机性始终取自 Go 的 `crypto/rand.Reader`。调用者不向 `Start` 或 `Respond` 提供随机性。
输入和线路字段具有包拥有的逐字段上限:密码和参与方 ID 限制为 4 KiB,上下文和会话 ID 限制为 1 KiB,关联数据限制为 64 KiB。这些不是聚合的消息大小限制。关联数据应绑定协议上下文,而不是携带大型负载;请使用摘要、Merkle 根、导出器或其他固定大小的承诺来表示大型外部数据。
## 验证
本仓库使用 `Taskfile.yml` 作为本地验证的统一入口:
```
task quick
task check
task check:changed
task docs:check
task bench
FUZZTIME=30s PARALLEL=2 task fuzz
FUZZ_RACE=0 GOMAXPROCS=4 FUZZTIME=8m PARALLEL=2 task fuzz
```
模糊测试目标位于 `.github/fuzz-targets.json`。GitHub 托管的拉取请求 CI 被故意设计得较为轻量,因为它运行的是不受信任的复刻代码:代码更改会运行 `go test ./...`,而仅包含 Markdown 的 PR 则在不设置 Go 环境的情况下运行文档验证。计划执行的托管流水线会运行 `govulncheck`、建议性的 `gosec`,以及每个目标 5 分钟的模糊回归测试,作为后台参考信号。在面向发布的更改之前,请在本地运行完整的本地门禁、更长时间的维护者机器模糊测试、漏洞扫描和建议性的 `gosec` 扫描。默认的模糊测试流水线在冒烟测试中保持启用竞争检测器;在 `task check` 已经覆盖了带有竞争检测的测试之后,可以使用 `FUZZ_RACE=0` 进行更长时间的测试活动。有关托管和自托管运行器的威胁模型,请参阅 `docs/ci-policy.md`。
发布就绪工作应记录确切的证据:提交 SHA、命令或工作流、模糊测试的持续时间、目标数量以及残余风险。依赖审查证据位于 `docs/dependency-review.md`;模糊测试活动证据位于 `docs/fuzz-evidence.md`;安全/规范审查证据位于 `docs/security-spec-audit.md`;Capslock 能力分析证据位于 `docs/capslock-report.md`;本地基准测试指南位于 `docs/performance.md`。外部审查者的范围和审查问题汇总在 `docs/external-review-handoff.md` 中;安全边界汇总在 `docs/threat-model.md` 中。下游发布验证说明位于 `docs/release-verification.md`。项目治理、安全门禁和 VEX 策略位于 `docs/governance.md`、`docs/security-gates.md` 和 `docs/vex.md` 中。
```
initiator, msgA, err := cpace.Start(initCfg)
responder, msgB, err := cpace.Respond(respCfg, msgA)
msgC, initSession, err := initiator.Finish(msgB)
respSession, err := responder.Finish(msgC)
key, err := initSession.Export([]byte("application key"), nil, 32)
```
发布策略:在独立审查完成并且满足 `docs/security-assessment.md` 中的发布标准之前,将标签保持在 `v0.x` 范围内。对于未来的候选发布版本,请使用 `docs/release-checklist.md`。在提交公共议题或拉取请求之前,请参阅 `CONTRIBUTING.md`;提交必须包含 DCO 签名。
## 许可证
BSD-3-Clause。请参阅 `LICENSE`。
标签:CFRG, CPace, EVTX分析, Go, IETF草案, JSONLines, P2P, peer-to-peer, Ristretto255, Ruby工具, SHA-512, 信息安全的数学实现, 加密协议, 安全通信, 密码学, 密钥交换, 密钥确认, 手动系统调用, 日志审计, 椭圆曲线, 网络安全, 身份鉴别, 隐私保护, 零信任