godaddy/asherah-ffi

GitHub: godaddy/asherah-ffi

基于 Rust 的应用层信封加密库,支持自动密钥轮换和多语言绑定,提供内存安全的三层密钥缓存与亚微秒级加解密性能。

Stars: 0 | Forks: 2

# Asherah 应用层加密,支持自动密钥轮换。Rust 实现, 并提供 Node.js、Python、.NET、Java、Ruby 和 Go 的绑定。 ## 什么是 Asherah? Asherah 实现了信封加密:数据使用随机数据密钥进行加密, 该数据密钥本身由中间密钥加密,而中间密钥则由 保存在 KMS 中的主密钥加密。密钥根据可配置的 间隔自动轮换,旧密钥仍可用于解密,而新数据始终 使用新密钥进行加密。 这种设计意味着应用代码永远不会处理原始主密钥,密钥轮换 透明地进行,且单个数据密钥泄露仅暴露 一条记录。 **KMS 后端:** AWS KMS(推荐)、[HashiCorp Vault Transit](docs/vault-transit-kms.md)(本地部署)、[AWS Secrets Manager](docs/secrets-manager-kms.md)(仅限迁移)、静态(仅限测试) **元存储:** DynamoDB、MySQL、Postgres、SQLite、内存(仅限测试) ## 语言绑定 | 语言 | 包 | 文档 | | -------- | ----------------------------------------------------------------------------------------------------------- | ------------------------- | | Node.js | npm 上的 [`asherah`](https://www.npmjs.com/package/asherah) | [README](asherah-node/) | | Python | PyPI 上的 [`asherah`](https://pypi.org/project/asherah) | [README](asherah-py/) | | .NET | [NuGet](https://www.nuget.org/packages/GoDaddy.Asherah.Encryption) 上的 `GoDaddy.Asherah.Encryption` | [README](asherah-dotnet/) | | Java | [GitHub Packages](https://github.com/godaddy/asherah-ffi/packages) 上的 `com.godaddy.asherah:appencryption` | [README](asherah-java/) | | Ruby | [GitHub Packages](https://github.com/godaddy/asherah-ffi/packages) 上的 `asherah` | [README](asherah-ruby/) | | Go | [`github.com/godaddy/asherah-ffi/asherah-go`](https://pkg.go.dev/github.com/godaddy/asherah-ffi/asherah-go) | [README](asherah-go/) | ## 平台支持 | 平台 | 架构 | 状态 | | -------- | --------------------- | --------- | | Linux | x86_64 (glibc) | 支持 | | Linux | x86_64 (musl) | 支持 | | Linux | ARM64 (glibc) | 支持 | | Linux | ARM64 (musl) | 支持 | | macOS | x86_64 | 支持 | | macOS | ARM64 (Apple Silicon) | 支持 | | Windows | x64 | 支持 | | Windows | ARM64 | 支持 | ## 快速开始 ``` const asherah = require('asherah'); asherah.setup({ serviceName: 'my-service', productId: 'my-product', metastore: 'memory', // testing only — use 'rdbms' or 'dynamodb' in production kms: 'static', // testing only — use 'aws' in production }); const ct = asherah.encryptString('partition', 'secret data'); const pt = asherah.decryptString('partition', ct); asherah.shutdown(); ``` 请参阅各绑定的 README 获取完整示例,包括 async API、 基于会话的用法以及生产配置。 ## 输入契约 有两类参数具有不同的规则: - **Partition ID**(租户/隔离标识符):`null`、`nil`、 `undefined` 和空字符串 `""` **始终是编程错误**。 绑定会在 API 边界使用对应语言原生的 异常类型拒绝它们——绝不会在元存储中写入退化的 ID 对应的行。(这比规范的 asherah-csharp / asherah-java 更严格, 后者会静默接受 null 并持久化 `_IK__service_product` 行。) - **Plaintext**(加密输入):`null`/`nil`/`undefined` 会作为 编程错误被拒绝。空 `String` 和空字节数组是 **有效**的明文,会产生真实的 `DataRowRecord` 信封, 并在解密时成功往返还原为空。**不要在调用方代码中短路空 明文加密**——空数据也是真实数据, 加密它是一个真实的密码学操作,跳过它会泄露 该值为空这一事实,形成侧信道。 - **Ciphertext**(解密输入):`null`/`nil`/`undefined` 以及空 字符串/字节全都会被拒绝——空输入不能作为有效的 `DataRowRecord` JSON 信封。 请参阅 [docs/input-contract.md](docs/input-contract.md) 获取每个绑定的 完整行为矩阵、异常类型和原理。 ## 性能 Rust 核心实现了亚微秒级的加密/解密。所有语言绑定的 同步操作保持在 2μs 以下。该表包括同步和异步 变体,以及与规范的 Go/C#/Java 实现的直接对比: 基准测试结果 — 热缓存,Apple M4 Max 请参阅各绑定的 README 获取详细的异步行为和每个元存储的 性能特征。 ## 架构:密钥层次与安全缓存 Asherah 采用四层密钥层次结构进行信封加密: ``` +------------------------------------------------------+ | KMS Backend | | (AWS KMS / HashiCorp Vault Transit API) | | | | Master Key -- never exposed, encrypt/decrypt via API | +------------------+-----------------------------------+ | encrypts +------------------v-----------------------------------+ | System Key (SK) | | Stored in metastore, cached in memory, auto-rotated | +------------------+-----------------------------------+ | encrypts +------------------v-----------------------------------+ | Intermediate Key (IK) | | Per-partition, stored in metastore, auto-rotated | +------------------+-----------------------------------+ | encrypts +------------------v-----------------------------------+ | Data Row Key (DRK) | | Unique per write -- effectively rotated every time | +------------------+-----------------------------------+ | encrypts v Your Data ``` ### 安全内存与分层密钥缓存 密钥在静态下受三层缓存保护,并具有硬件强制的 内存保护: ``` TIER 1: mlock'd Slab (hot cache, ~400ns access) ======================================================== Guard Page [PROT_NONE -- segfaults on access] +----------------------------------------------------+ | mlock'd Page (4KB, pinned in RAM, never swapped) | | | | Slot 0: Coffer Left (XOR'd master key half) | | Slot 1: Coffer Right (random, key derivation) | | [neither half alone reveals the key] | | | | Slot 2: SK decrypt key <-- hot cache (LRU) | | Slot 3: IK decrypt key <-- hot cache (LRU) | | Slot 4: [transient op] <-- acquired/released | | ... | | Slot N: [free] | +----------------------------------------------------+ Guard Page [PROT_NONE -- segfaults on access] Canary bytes between guard pages and data detect buffer overflows at runtime. TIER 2: Encrypted Enclaves (cold cache, ~1us access) ======================================================== Regular heap memory (not mlock'd, can be swapped) +----------------------------------------------------+ | Enclave { id, ciphertext, data_len } | | ciphertext = AES-256-GCM(key, coffer_master) | | On access: decrypt into Tier 1 slab slot | | Promoted to hot cache after first use | +----------------------------------------------------+ Each CryptoKey holds an Enclave. When the hot cache is full, LRU eviction frees a slab slot. The evicted key remains safe in its Enclave (encrypted at rest). TIER 3: Metastore (persistent, ~1ms access) ======================================================== DynamoDB / MySQL / Postgres / SQLite +----------------------------------------------------+ | EnvelopeKeyRecord { id, created, encrypted_key } | | encrypted_key = AES-256-GCM(key, parent_key) | | Loaded on cold start or cache miss | | Decrypted through the key hierarchy (IK->SK->KMS)| +----------------------------------------------------+ ``` **Tier 1 命中**(典型加密/解密):解密后的密钥已经位于 mlock 的 slab 槽中——零密码学开销,只需一次指针读取。这就是 热缓存加密约为 ~400ns 的原因。 **Tier 1 未命中,Tier 2 命中**:密钥的 Enclave(堆内存中 AES-256-GCM 加密的密文)使用来自 slab 的 Coffer 主密钥进行解密, 放入空闲槽中,并提升至热缓存。 **Tier 2 未命中**(冷启动):密钥从元存储加载, 通过密钥层次解密(KMS 解密 SK,SK 解密 IK), 密封到 Enclave 中,并提升至 slab 热缓存。 **Coffer**:Enclave 加密的主密钥使用 XOR + 哈希派生 分割在两个 mlock 的槽中。单独的任何一个槽都无法揭示该 密钥。在启动时使用 OS 熵进行一次初始化。 ### 会话与密钥缓存 在内存层之上,Asherah 维护带有 stale-while-revalidate 策略的逻辑缓存,以防止缓存过期时出现惊群效应: ``` Request --> Session Cache (LRU, per-factory) | miss v IK Cache (stale-while-revalidate) | miss v SK Cache (shared, stale-while-revalidate) | miss v Metastore load --> Tier 2/1 promotion ``` 在缓存过期时,会立即返回过期密钥,同时后台 刷新会从元存储加载最新版本。 ## 测试 - **127 个 Rust 单元测试**,涵盖核心加密引擎、密钥管理、 元存储适配器和内存保护 - **64 个 .NET 测试**(34 个核心 + 30 个兼容层),涵盖 net8.0 和 net10.0 - **49 个 Node.js 测试**,包括异步上下文、unicode、二进制边界情况和 Factory/Session API - **21 个 Go 测试**,涵盖 Factory/Session API 和兼容层 - **21 个 Python 测试**,包括基于会话和异步的 API - **16 个 Java 测试**,包括 JNI 生命周期和异步 CompletableFuture - **74 个 Ruby 测试**,包括线程安全、会话生命周期和异步 回调 - **5 个跨语言互操作性测试**,验证 Python、Node.js、Rust 和 Ruby 加密/解密的兼容性 - **6 个 Fuzz 目标**,用于 Cargo-fuzz 持续模糊测试 - **内存安全**:每个 PR 都运行 Miri(未定义行为检测)、AddressSanitizer 和 Valgrind - **12 个发布试运行作业**,复现发布流水线中每个独特的编译路径 - **56+ 个 CI 作业**,在每次拉取请求时跨越 x86_64 和 ARM64 运行 ``` # 运行所有测试 scripts/test.sh --all # 独立测试模式 scripts/test.sh --unit scripts/test.sh --integration # requires Docker (MySQL, Postgres, DynamoDB) scripts/test.sh --bindings # requires language toolchains scripts/test.sh --interop scripts/test.sh --lint scripts/test.sh --sanitizers # Miri, AddressSanitizer, Valgrind scripts/test.sh --fuzz # requires nightly ``` ## 项目结构 | 目录 | 描述 | | ----------------- | -------------------------------- | | `asherah/` | Rust 核心库 | | `asherah-node/` | Node.js 绑定 | | `asherah-py/` | Python 绑定 | | `asherah-dotnet/` | .NET 绑定 | | `asherah-java/` | Java 绑定 (JNI) | | `asherah-ruby/` | Ruby 绑定 | | `asherah-go/` | Go 绑定 (purego, 无 CGO) | | `asherah-ffi/` | 用于语言绑定的 C ABI | | `asherah-server/` | gRPC sidecar 服务器 | | `samples/` | 各语言用法示例 | | `benchmarks/` | 跨语言基准测试套件 | ## 安全性 - **mlock 内存**:所有密钥材料都位于固定在 RAM 中的页上 (`mlock`),防止操作系统将机密交换到磁盘 - **保护页**:通过在受保护内存区域周围设置 硬件强制的保护页,捕获缓冲区溢出和下溢 - **Canary 字节**:通过缓冲区边界处的随机 canary 值提供可选的缓冲区溢出检测 - **释放时擦除**:所有密钥材料在内存释放前 都经过密码学擦除——释放的页面中不留残余机密 - **核心转储保护**:在进程初始化时禁用,以 防止机密出现在崩溃转储中 - **Coffer 密钥分割**:Enclave 主密钥使用 XOR + 哈希派生 分割在两个 mlock 的槽中——单独的任何一个槽都无法揭示该密钥 - **AES-256-GCM Enclaves**:常规内存中静态的密钥使用 认证加密进行加密;只有 mlock 的 Coffer 才能解密它们 ## 许可证 [Apache-2.0](LICENSE)
标签:AWS KMS, AWS Secrets Manager, DynamoDB, Ffi, GNU通用公共许可证, Go, Godaddy, HashiCorp Vault, HTTP工具, JS文件枚举, KMS, meg, MITM代理, Node.js, Postgres, ProjectDiscovery, Python, Python工具, Ruby, Ruby工具, Rust核心, SQLite, 信封加密, 信息安全, 可视化界面, 多人体追踪, 子域名变形, 密码学, 密钥存储, 应用层加密, 手动系统调用, 数据保护, 无后门, 日志审计, 测试用例, 知识库, 自动密钥轮换, 跨语言绑定, 逆向工具, 通知系统, 静态数据加密