deadpoets/secmem
GitHub: deadpoets/secmem
一个纯 Go 实现的机密内存库,通过堆外锁定内存、内核隔离和保证擦除来保护进程内的私钥、token 和密码等敏感数据。
Stars: 1 | Forks: 0
# secmem
[](https://pkg.go.dev/github.com/deadpoets/secmem)
[](https://github.com/deadpoets/secmem/actions/workflows/ci.yml)
[](https://goreportcard.com/report/github.com/deadpoets/secmem)
强化内存中的机密信息 —— 让私钥、token 和密码远离 Go 的垃圾回收堆,将其置于操作系统锁定且被排除在 swap 之外的内存页中,并在平台允许的情况下,使其免于出现在 core dumps 及其他进程中。释放时,字节会通过架构专用的例程被擦除,并且仅能通过借用闭包访问,从而确保明文在完成使命后即刻消亡。
纯 Go 实现 (`CGO_ENABLED=0`),仅依赖于 `golang.org/x/sys`。
## 诚信为先
每一项保证都按平台逐一说明,并明确指出其**无法**防范的内容。一个夸大其安全保证的安全库比没有安全库更糟糕。因此:
- 平台无法提供的保护会通过
[`Capabilities`](https://pkg.go.dev/github.com/deadpoets/secmem#Capabilities) 进行**报告**,
绝不会默默跳过。在启动时调用一次
[`Probe`](https://pkg.go.dev/github.com/deadpoets/secmem#Probe) 即可查看当前生效的保护措施。
- 没有可锁定堆外内存的平台会**响亮地报错**
(`ErrNoSecureMemory`),而不是退化为不受保护的堆内存 —— 除非你通过 `WithInsecureFallback()` 显式选择允许。
- 下文所述的每一项声明都经过了测试验证。guard pages 确实会触发错误;`memfd_secret` 的隔离已通过 `/proc/self/mem` 进行检查;擦除、脱敏和不触发 panic 的承诺均已通过 fuzz 测试。关于测试套件运行过的内核列表,请参见 [`KERNELS.md`](KERNELS.md)。
## 安装
```
go get github.com/deadpoets/secmem
```
## 快速开始
```
buf, err := secmem.NewBuffer(rawKey) // rawKey is wiped after the copy
if err != nil {
return err
}
defer buf.Destroy() // always defer immediately
err = buf.WithBytesErr(func(borrowed []byte) error {
// borrowed is valid ONLY inside this closure — never store it.
return sign(borrowed, msg)
})
```
对于你持有并可能记录到日志中的值,请将它们包装在
[`Secret`](https://pkg.go.dev/github.com/deadpoets/secmem#Secret) 中:它会通过 `fmt`、`encoding/json` 和 `log/slog` 将其渲染为
`[REDACTED]`。若要对自由格式的日志文本进行脱敏,[`redact`](https://pkg.go.dev/github.com/deadpoets/secmem/redact)
子包提供了一个 `slog.Handler` 包装器。
## 平台保证矩阵
`✓` 强制执行 · `⚠` 尽力而为(报告失败,但非致命错误) · `✗` 未提供 · **LOUD** 仅在显式选择时启用。此表是威胁模型的核心;关于这些措施都无法防范的内容,请参见 [THREAT-MODEL.md](THREAT-MODEL.md)。
| 保护措施 | linux/amd64·arm64 (≥5.14) | linux (较旧 / 32位) | darwin | windows | 其他 |
|---|---|---|---|---|---|
| 远离 Go 堆 | ✓ memfd_secret | ✓ mmap | ✓ mmap | ✓ VirtualAlloc | **LOUD** 仅限堆 |
| 无 swap (已锁定) | ✓ | ✓ mlock | ✓ mlock | ✓ VirtualLock | ✗ |
| 内核隔离 (对 root / ptrace / `/proc//mem` 不可见) | ✓ memfd_secret | ✗ (退化为 mlock) | ✗ | ✗ | ✗ |
| 排除在崩溃转储之外 | ⚠ MADV_DONTDUMP | ⚠ MADV_DONTDUMP | ✗ | ⚠ WER 排除 | ✗ |
| 不通过 fork 继承 | ⚠ MADV_DONTFORK | ⚠ MADV_DONTFORK | ✗ | n/a | ✗ |
| 无 THP/KSM 机密副本 | ✓ madvise | ✓ madvise | n/a | n/a | ✗ |
| 销毁时保证擦除 | ✓ asm + 缓存刷新 | ✓ (amd64/arm64 asm; 否则 ⚠ 常数时间) | ✓ asm | ✓ asm (amd64) | ⚠ 常数时间存储 |
| Guard pages + 溢出 canary | ✓ | ✓ | ✓ | ✓ | ✗ (堆回退) |
| 寄存器 + 栈 + 堆清理 ([`Scrub`](https://pkg.go.dev/github.com/deadpoets/secmem#Scrub)) | ✓ 需开启 `GOEXPERIMENT=runtimesecret` | ✓ 如果设置 (amd64/arm64);否则帧清理 | 仅限帧清理 | 仅限帧清理 | 帧清理 / ✗ |
| 密封时加密 ([`Seal`](https://pkg.go.dev/github.com/deadpoets/secmem#SecureBuffer.Seal)) | ✗ | ✗ | ✗ | ✓ CryptProtectMemory | ✗ |
| 进程强化 ([`HardenProcess`](https://pkg.go.dev/github.com/deadpoets/secmem#HardenProcess)) | ✓ dumpable=0, no-new-privs | ✓ | ✗ | ✓ ACG + 严格句柄 | ✗ |
| 响亮报错,从不默默降级 | ✓ | ✓ | ✓ | ✓ | ✓ (**LOUD** 显式选择) |
该套件已在真实的 **linux/amd64 和 linux/arm64** 硬件上执行,
涵盖内核版本从 5.10 到 7.x(参见 [`KERNELS.md`](KERNELS.md))。在 arm64
(Ampere Altra) 上,`memfd_secret` L4 路径、guard-page 错误、
`/proc/self/mem` 隔离证明以及架构专用的擦除汇编代码
均测试通过。`memfd_secret` 是否生效取决于内核的
`CONFIG_SECRETMEM`,而不仅仅是版本号 —— 如果缺失,secmem 会针对每一次分配如实报告“回退”并使用 `mmap`+`mlock`。
guard pages 和 canary 是一种**内存安全漏洞捕获器,而非机密性控制手段** —— 它们能捕获意外的上溢/下溢,但对于拥有特权的进程内存读取者却无能为力(那是
`memfd_secret` 的职责)。Windows 密封状态密码提高防范休眠机密内存转储的门槛;它并非冷启动保护。两者在 godoc 和威胁模型中均有详细说明。
## 模块
- **`secmem`** (当前模块) —— 包含 `SecureBuffer`、`SecureArena`、`Secret`、
`Capabilities`/`Probe`、`Scrub` 以及进程强化辅助工具。仅依赖于
`golang.org/x/sys`。
- **`secmem/redact`** —— 包含用于边界级别日志清理的 `Sanitizer` 和 `slog.Handler`。仅使用标准库。
## 文档
完整的 API 文档、每个符号可运行的 `Example` 以及每个符号的保证说明均位于
[pkg.go.dev](https://pkg.go.dev/github.com/deadpoets/secmem)。关于端到端
程序,[`examples/`](examples/) 提供了一个密码注册/登录流程以及一个
可用的、经过强化的 SSH 代理 —— 每一个都在真实的 I/O、
并发和关机操作下组合使用了该库。请从
包概述开始阅读,然后通过 [`THREAT-MODEL.md`](THREAT-MODEL.md) 了解限制,
通过 [`TESTING.md`](TESTING.md) 查看每个声明是如何被证明的(或为何无法被证明),
通过 [`ENVIRONMENTS.md`](ENVIRONMENTS.md) 了解在 root / 非 root /
容器下的行为,通过 [`KERNELS.md`](KERNELS.md) 了解该套件运行过的 Linux 内核,
并通过 [`WINDOWS.md`](WINDOWS.md) 了解 Windows 版本/构建信息。
## 贡献
欢迎提交 Bug 修复、强化改进以及无回归的性能提升 —— 请参阅
[CONTRIBUTING.md](CONTRIBUTING.md) 了解工作流(每一个 PR,包括
维护者的,都要经过审查和 CI 测试)。发现了漏洞?请参阅
[SECURITY.md](SECURITY.md) —— 请勿将其作为公开 issue 提交。
参与受[行为准则](CODE_OF_CONDUCT.md)约束。
## 许可证
Apache-2.0。请参阅 [LICENSE](LICENSE)。
标签:EVTX分析, Go语言, HTTP工具, 内存安全, 日志审计, 机密保护, 程序破解, 系统编程, 防御性编程, 防御绕过