10 个版本 (6 个破坏性更新)
0.7.0 | 2022年4月14日 |
---|---|
0.6.0 | 2021年6月21日 |
0.5.0 | 2021年6月18日 |
0.4.1 | 2021年6月18日 |
0.1.1 | 2021年6月13日 |
#999 in 密码学
每月 1,824 次下载
在 4 个crate中使用 (3 个直接使用)
55KB
1K SLoC
serde-encrypt
🔐 加密所有可序列化对象。
Alice Bob
+-----------------------------------+ +-----------------------------------+
| #[derive(Serialize, Deserialize)] | | #[derive(Serialize, Deserialize)] |
| struct Message | | struct Message |
+-----------------------------------+ +-----------------------------------+
| .encrypt() ^
v | ::decrypt()
+-----------------------------------+ +-----------------------------------+
| struct EncryptedMessage | | struct EncryptedMessage |
+-----------------------------------+ +-----------------------------------+
| .serialize() ^
v | ::deserialize()
+-----------------------------------+ +-----------------------------------+
| struct Vec<u8> | -----> | struct Vec<u8> |
+-----------------------------------+ +-----------------------------------+
概述
serde-encrypt 对实现 serde::{Serialize, Deserialize
} 的任何 struct
和 enum
进行加密和解密。
serde-encrypt 支持两种加密方式:共享密钥加密 (XChaCha20-Poly1305) 和 公钥加密 (使用 X25519 密钥交换的 XChaCha20-Poly1305),这两种加密方式都被认为足够安全。
serde-encrypt 可选地支持 no_std 环境。
[dependencies]
serde-encrypt = "(version)" # If you use std
serde-encrypt = {version = "(version)", default-features = false} # If you need no_std
示例
从 共享密钥加密测试 中的良好入门示例。
如果你和你的通信伙伴已经有了共享密钥,只需将 SerdeEncryptSharedKey
特征实现到你的 Serialize
和 Deserialize
数据类型中。
#[derive(Debug, Serialize, Deserialize)]
struct Message {
content: String,
sender: String,
}
impl SerdeEncryptSharedKey for Message {
type S = BincodeSerializer<Self>; // you can specify serializer implementation (or implement it by yourself).
}
然后,你可以将 Message
序列化成加密形式的 Vec<u8>
。
// Alternative:
// const SHARED_KEY: SharedKey = SharedKey::new_const([0u8; 32]);
let shared_key = SharedKey::new([0u8; 32]); // or your peer reads from elsewhere.
let msg = Message {
content: "I ❤️ you.".to_string(),
sender: "Alice".to_string(),
};
let encrypted_message = msg.encrypt(&shared_key)?;
let serialized_encrypted_message: Vec<u8> = encrypted_message.serialize();
在通信伙伴收到二进制文件后,他们可以解密并将它反序列化为 Message
。
let shared_key = SharedKey::new([0u8; 32]);
let encrypted_message = EncryptedMessage::deserialize(serialized_encrypted_message)?;
let msg = Message::decrypt_owned(&encrypted_message, &shared_key);
更多示例...
功能和用例
功能比较
SerdeEncryptSharedKey |
SerdeEncryptSharedKeyDeterministic |
SerdeEncryptPublicKey |
|
---|---|---|---|
(a)是对称加密吗? | 对称加密 | 对称加密 | 非对称加密 |
确定性?(1) | 否 | 是 | 否 |
性能 | 高 | 高 | 低 |
(1)确定性加密总是从给定的明文产生相同的密文。更易受攻击但可用于密文中匹配(例如,RDBMS的加密索引等值搜索)。
加密算法
SerdeEncryptSharedKey |
SerdeEncryptSharedKeyDeterministic |
SerdeEncryptPublicKey |
|
---|---|---|---|
密钥交换 | - | - | X25519 |
加密 | XChaCha20 | XChaCha20 | XChaCha20 |
消息认证 | Poly1305 | Poly1305 | Poly1305 |
nonce (2) | XSalsa20(随机24字节) | 固定24字节 | XSalsa20(随机24字节) |
用于nonce的Rng (3) | ChaCha20Rng | - | ChaCha20Rng |
实现 | XChaCha20Poly1305 | XChaCha20Poly1305 | ChaChaBox |
(2)“一次性使用”:使加密非确定性。尽管每个加密的nonce不是秘密的,但不同加密之间的nonce必须不同,以便攻击者更难猜测明文。
(3)随机数生成器。
序列化器
设计时,Crate用户可以选择甚至自己实现序列化表示。
目前,以下序列化器是内置的。
BincodeSerializer
(仅std
功能)- 在大多数情况下,是
std
的最佳选择,以减少消息大小。
- 在大多数情况下,是
PostcardSerializer
- 在大多数情况下,是no_std的最佳选择,以减少消息大小。
CborSerializer
- 消息大小较大,但可以处理复杂的serde类型。请参阅加密/解密复杂serde类型示例以检查只有
CborSerializer
可以序列化的serde类型。 - 在
serde-encrypt-sgx
中可用。- bincode和postcard crate不能与Rust SGX SDK一起编译
- 消息大小较大,但可以处理复杂的serde类型。请参阅加密/解密复杂serde类型示例以检查只有
用例
SerdeEncryptSharedKey
- 消息发送方和接收方已经持有共享密钥。
- 需要通过任何安全方式交换共享密钥,但希望加密/解密速度快(例如,大量消息通信)。
SerdeEncryptSharedKeyDeterministic
- 仅当您需要确定性加密以在密文中进行匹配时。
- 请注意,这比
SerdeEncryptSharedKey
更易受攻击,因为攻击者可以在密文中找到重复的模式,然后猜测明文中的重复模式。
SerdeEncryptPublicKey
- 交换
SharedKey
。 - 快速发送/接收少量消息,无需秘密共享密钥。
- 交换
Rust SGX SDK支持
使用serde-encrypt-sgx crate。
功能标志
std
(serde-encrypt
[默认];serde-encrypt-core
[默认])- 实现
std::error::Error
trait到serde_encrypt::Error
。 - 随机数生成器通过
SeedableRng::from_entropy()
创建,这在OS可用环境中被认为是更安全的。 BincodeSerializer
可用。
- 实现
实现
包
serde-encrypt
是一个cargo工作空间项目,其中包含两个crate
serde-encrypt-core
- 加密/解密实现。
- 序列化/反序列化特剧行为。
- RNG(随机数生成器)单例特剧行为。
serde-encrypt
(依赖于serde-encrypt-core
)- 序列化/反序列化实现。
- RNG单例实现。
serde-encrypt-sgx
crate也作为单独的仓库提供。它与serde-encrypt
处于同一层。
为了在 Rust SGX SDK 中使用 serde,人们应该使用分支版本 serde-sgx。此外,Rust SGX SDK 仅使用旧版本的 rustc 进行编译(例如,目前是 nightly-2020-10-25),即使是简单的 no_std crate 也可能无法构建(例如,spin crate 就无法构建)。
另一个选择是使用功能标志在这个仓库内部创建 serde-encrypt-sgx
,但它会破坏最新 rustc 中的 cargo build --all-features
。
加密
使用 crypto_box crate 进行公钥加密和共享密钥加密。
NaCl-family 库(例如,libsodium,TweetNaCl)的 crypto_box 公钥认证加密方案的纯 Rust 实现,它将 X25519 Diffie-Hellman 函数和 XSalsa20Poly1305 认证加密密文组合成一个椭圆曲线集成加密方案(ECIES)。
序列化
在加密之前,将要加密的 struct
和 enum
进行序列化。内置序列化器列在这里 这里。
用户也可以自己实现 TypedSerialized trait,以获得更好的序列化。
变更日志
请参阅 CHANGELOG.md。
许可协议
根据您的选择,许可协议为 Apache License, Version 2.0 或 MIT license。
除非您明确说明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在 serde-encrypt 中的任何贡献,都应按上述方式双重许可,不附加任何额外条款或条件。
依赖关系
~5MB
~101K SLoC