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 密码学

Download history 666/week @ 2024-04-14 859/week @ 2024-04-21 402/week @ 2024-04-28 394/week @ 2024-05-05 351/week @ 2024-05-12 674/week @ 2024-05-19 470/week @ 2024-05-26 519/week @ 2024-06-02 396/week @ 2024-06-09 429/week @ 2024-06-16 363/week @ 2024-06-23 320/week @ 2024-06-30 492/week @ 2024-07-07 392/week @ 2024-07-14 577/week @ 2024-07-21 329/week @ 2024-07-28

每月 1,824 次下载
4 个crate中使用 (3 个直接使用)

MIT/Apache

55KB
1K SLoC

serde-encrypt

crates.io Crates.io docs.rs MSRV ci codecov License: MIT License: Apache 2.0

serde-encrypt logo

🔐 加密所有可序列化对象。

               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} 的任何 structenum 进行加密和解密。

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 特征实现到你的 SerializeDeserialize 数据类型中。

#[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一起编译

用例

  • SerdeEncryptSharedKey
    • 消息发送方和接收方已经持有共享密钥。
    • 需要通过任何安全方式交换共享密钥,但希望加密/解密速度快(例如,大量消息通信)。
  • SerdeEncryptSharedKeyDeterministic
    • 仅当您需要确定性加密以在密文中进行匹配时。
    • 请注意,这比SerdeEncryptSharedKey更易受攻击,因为攻击者可以在密文中找到重复的模式,然后猜测明文中的重复模式。
  • SerdeEncryptPublicKey
    • 交换SharedKey
    • 快速发送/接收少量消息,无需秘密共享密钥。

Rust SGX SDK支持

使用serde-encrypt-sgx crate。

功能标志

  • stdserde-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)。

序列化

在加密之前,将要加密的 structenum 进行序列化。内置序列化器列在这里 这里

用户也可以自己实现 TypedSerialized trait,以获得更好的序列化。

变更日志

请参阅 CHANGELOG.md

许可协议

根据您的选择,许可协议为 Apache License, Version 2.0MIT license

除非您明确说明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在 serde-encrypt 中的任何贡献,都应按上述方式双重许可,不附加任何额外条款或条件。

依赖关系

~5MB
~101K SLoC