brndnmtthws/dryoc
GitHub: brndnmtthws/dryoc
一个纯 Rust 实现的加密库,旨在作为 libsodium 的替代方案,通过防误用设计和受保护内存特性让开发者更安全地使用加密原语。
Stars: 335 | Forks: 19
[](https://docs.rs/dryoc) [](https://crates.io/crates/dryoc) [](https://github.com/brndnmtthws/dryoc/actions/workflows/build-and-test.yml) [](https://app.codecov.io/gh/brndnmtthws/dryoc/)
# dryoc: Don't Roll Your Own Crypto™[^1]
dryoc 是一个纯 Rust 编写的通用加密库,且难以被误用。它基于优秀的
[libsodium](https://github.com/jedisct1/libsodium) 库,但是使用_纯_ Rust 实现。它
还包含了贯穿始终的受保护内存特性,这使得构建安全、健壮且可靠的加密软件变得极其简单。该库最初的目标是提供一个 libsodium 的纯 Rust 替代方案。

本项目的目的是提供一个纯 Rust 的、基本可以开箱即用的
libsodium 替代方案。该库具有与 libsodium 几乎相同的人体工程学设计(在 dryoc 中被称为 _Classic_ API),使得熟悉
libsodium 的人几乎可以互换地使用该库。虽然
API 与 libsodium 不是 100% 相同,但大多数函数具有相同或非常相似的签名。
除了 Classic API 之外,还有一个 _Rustaceous_ API,旨在为 libsodium 的核心功能提供地道的 Rust 实现:公钥和密钥认证加密以及通用加密工具。
并非 libsodium 的所有功能都在此实现,要么是因为在其他 crate 中有更好的实现,要么是因为它们不作为此 crate 的一部分而必须存在。
此外,得益于 Rust 的安全特性,此 crate 提供了异常安全的加密功能。Rustaceous API 旨在让你难以弄巧成拙。然而,值得注意的是,如果你执意要犯错误,你仍然可以做到(无论是通过泄露私有数据、使用不安全的硬件、OPSEC 问题等方式)。
有关用法示例,请参阅
[官方文档](https://docs.rs/dryoc/latest/dryoc/) 或
[集成测试](/tests/integration_tests.rs)。
## 功能
* 100% 纯 Rust,没有隐藏的 C 语言库
* 基本不含不安全代码[^2]
* 难以误用,帮助你避免常见且代价高昂的加密错误
* 通过 Classic 和 Rustaceous API 实现了许多 libsodium 功能
* 受保护的内存处理(`mprotect()` + `mlock()`,以及 Windows 等效实现)
* 支持 [Serde](https://serde.rs/)(通过 `features = ["serde"]`)
* 支持 [wincode](https://crates.io/crates/wincode),用于 Rustaceous box 类型的直接二进制序列化(通过 `features = ["wincode"]`)
* 在 nightly 版本中提供[_可移植_ SIMD](https://doc.rust-lang.org/std/simd/index.html) 实现,使用 `features = ["simd_backend", "nightly"]`:
* Blake2b(由通用哈希、密码哈希和密钥派生使用)
* Argon2 块混合(由密码哈希使用)
* Salsa20(由 XSalsa20-Poly1305 secretbox 使用)
* Poly1305(由一次性认证和密钥盒使用)
* [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek)(由公钥/私钥函数使用)在构建时选择其自己的串行或 x86_64 向量后端
* [SHA2](https://github.com/RustCrypto/hashes/tree/master/sha2)(由密封盒使用)包含用于 AVX2 的 SIMD 实现
* [ChaCha20](https://github.com/RustCrypto/stream-ciphers/tree/master/chacha20)(由流式接口使用)包含用于 NEON、AVX2 和 SSE2 的 SIMD 实现
## Rust 版本
dryoc 使用 Rust 2024 edition 并要求 Rust 1.89 或更新版本,正如
`Cargo.toml` 中的 `rust-version` 所声明的那样。
Rust 2024 保留了 `gen` 作为关键字。请使用诸如
`Key::generate()` 的生成 API。出于兼容性考虑,现有的 `gen` API 仍可通过原始标识符
语法(如 `Key::r#gen()`)使用,并将在
未来的版本中被弃用。
`simd_backend` 和 `nightly` 特性启用了 dryoc 的可移植 SIMD
后端。特定于 CPU 的依赖后端和本地基准测试也可能
受益于针对特定目标的 `RUSTFLAGS`:
* 对于 AVX2,设置 `RUSTFLAGS=-Ctarget-cpu=haswell -Ctarget-feature=+avx2`
* 对于 SSE2,设置 `RUSTFLAGS=-Ctarget-feature=+sse2`
* 对于 NEON,设置 `RUSTFLAGS=-Ctarget-feature=+neon`
* 对于本地 Apple Silicon 基准测试,使用 `RUSTFLAGS=-Ctarget-cpu=native`。
NEON 是 AArch64 macOS 基准目标的一部分,因此添加
`-Ctarget-feature=+neon` 预计不会改变本地测试结果。
Curve25519 后端由 `curve25519-dalek` 选择,而不是由 dryoc 的
`simd_backend` 特性选择。
_请注意,最终该项目将收敛于所有核心算法的可移植 SIMD 实现,这将适用于 LLVM 支持的所有平台,
而不是依赖手写汇编或内联函数,但这项目前仍在进行中_。
请参阅 [BENCHMARKS.md](BENCHMARKS.md) 以获取并排的软件和 SIMD 基准测试
结果。
## 可选序列化
启用 `serde` 以派生 [`serde::Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html)
和 [`serde::Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html)
用于支持的数据结构。
启用 `wincode` 以派生 [`wincode::SchemaWrite`](https://docs.rs/wincode/latest/wincode/trait.SchemaWrite.html)
和 [`wincode::SchemaRead`](https://docs.rs/wincode/latest/wincode/trait.SchemaRead.html)
用于受支持的 Rustaceous box 类型,包括 `DryocBox` 和
`DryocSecretBox`。
## 项目状态
目前已实现或等待实现以下 libsodium 功能:
* [x] [公钥加密](https://docs.rs/dryoc/latest/dryoc/dryocbox/index.html) (`crypto_box_*`) [libsodium 链接](https://doc.libsodium.org/public-key_cryptography)
* [x] [密钥加密](https://docs.rs/dryoc/latest/dryoc/dryocsecretbox/index.html) (`crypto_secretbox_*`) [libsodium 链接](https://doc.libsodium.org/secret-key_cryptography)
* [x] [点乘标量乘法](https://docs.rs/dryoc/latest/dryoc/classic/crypto_core/index.html) (`crypto_scalarmult*`) [libsodium 链接](https://doc.libsodium.org/advanced/scalar_multiplication)
* [x] 内存清零 (`sodium_memzero`),使用 [zeroize](https://crates.io/crates/zeroize) [libsodium 链接](https://doc.libsodium.org/memory_management)
* [x] [生成随机数据](https://docs.rs/dryoc/latest/dryoc/rng/index.html) (`randombytes_buf`) [libsodium 链接](https://doc.libsodium.org/generating_random_data)
* [x] [加密流](https://docs.rs/dryoc/latest/dryoc/dryocstream/index.html) (`crypto_secretstream_*`) [libsodium 链接](https://doc.libsodium.org/secret-key_cryptography/secretstream)
* [x] [内存锁定](https://docs.rs/dryoc/latest/dryoc/protected/index.html) (`sodium_mlock`、`sodium_munlock`、`sodium_mprotect_*`) [libsodium 链接](https://doc.libsodium.org/memory_management)
* [x] [加密相关消息](https://docs.rs/dryoc/latest/dryoc/utils/fn.increment_bytes.html) (`sodium_increment`) [libsodium 链接](https://doc.libsodium.org/secret-key_cryptography/encrypted-messages)
* [x] [通用哈希](https://docs.rs/dryoc/latest/dryoc/generichash/index.html) (`crypto_generichash_*`) [libsodium 链接](https://doc.libsodium.org/hashing/generic_hashing)
* [x] [密钥认证](https://docs.rs/dryoc/latest/dryoc/auth/index.html) (`crypto_auth*`) [libsodium 链接](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication)
* [x] [一次性认证](https://docs.rs/dryoc/latest/dryoc/onetimeauth/index.html) (`crypto_onetimeauth_*`) [libsodium 链接](https://doc.libsodium.org/advanced/poly1305)
* [x] [密封盒](https://docs.rs/dryoc/latest/dryoc/dryocbox/struct.DryocBox.html#method.seal) (`crypto_box_seal*`) [libsodium 链接](https://doc.libsodium.org/public-key_cryptography/sealed_boxes)
* [x] [密钥派生](https://docs.rs/dryoc/latest/dryoc/kdf/index.html) (`crypto_kdf_*`) [libsodium 链接](https://doc.libsodium.org/key_derivation)
* [x] [密钥交换](https://docs.rs/dryoc/latest/dryoc/kx/index.html) (`crypto_kx_*`) [libsodium 链接](https://doc.libsodium.org/key_exchange)
* [x] [公钥签名](https://docs.rs/dryoc/latest/dryoc/sign/index.html) (`crypto_sign_*`) [libsodium 链接](https://doc.libsodium.org/public-key_cryptography/public-key_signatures)
* [x] [Ed25519 转 Curve25519](https://docs.rs/dryoc/latest/dryoc/classic/crypto_sign_ed25519/index.html) (`crypto_sign_ed25519_*`) [libsodium 链接](https://doc.libsodium.org/advanced/ed25519-curve25519)
* [x] [短输入哈希](https://docs.rs/dryoc/latest/dryoc/classic/crypto_shorthash/index.html) (`crypto_shorthash`) [libsodium 链接](https://doc.libsodium.org/hashing/short-input_hashing)
* [x] [密码哈希](https://docs.rs/dryoc/latest/dryoc/pwhash/index.html) (`crypto_pwhash_*`) [libsodium 链接](https://doc.libsodium.org/password_hashing/default_phf)
以下 libsodium 功能要么不完整,要么未作为公共
API 暴露,要么未实现;你可以在其他
crate 中找到等效功能:
* 独立的[流密码](https://doc.libsodium.org/advanced/stream_ciphers) API(请直接使用 [salsa20](https://crates.io/crates/salsa20) crate)
* [辅助函数](https://doc.libsodium.org/helpers)和[填充](https://doc.libsodium.org/padding)工具
* [高级功能](https://doc.libsodium.org/advanced):
* [Scrypt](https://doc.libsodium.org/advanced/scrypt)(请直接使用 [scrypt](https://crates.io/crates/scrypt) crate)
* [有限域算术](https://doc.libsodium.org/advanced/point-arithmetic)(请尝试使用 [curve25519-dalek](https://crates.io/crates/curve25519-dalek) crate)
## 值得一提的其他基于 NaCl 的 Rust 实现
* [sodiumoxide](https://crates.io/crates/sodiumoxide)
* [crypto_box](https://crates.io/crates/crypto_box)
[^1]: 实际上并未注册商标。
[^2]: [protected] mod 中描述的受保护内存功能需要
自定义内存分配、系统调用和指针运算,这在 Rust 中是
不安全的。一些可选的 SIMD 代码,包括依赖项提供的 SIMD
实现和小的内部辅助函数,可能包含不安全代码。特别
是,许多 SIMD 实现由于使用了汇编或内联函数而被认为是
“不安全的”,然而如果没有基于 SIMD 的加密,你可能会
面临时序攻击的风险。请参阅
[rustdoc 不安全代码摘要](https://docs.rs/dryoc/latest/dryoc/#unsafe-code) 以了解此 crate 中非测试部分的不安全代码清单。
标签:libsodium替代, Rust, 公钥加密, 内存保护, 加密库, 可视化界面, 安全, 密码学, 开源库, 手动系统调用, 搜索引擎爬虫, 私钥加密, 纯Rust实现, 网络流量审计, 超时处理, 身份验证加密, 软件开发, 通知系统, 防误用, 零依赖