laysakura / serde-encrypt

🔐 Encrypts all the Serialize.
Apache License 2.0
175 stars 6 forks source link
encryption libsodium serde serde-encrypt serialization x25519 xchacha20-poly1305

serde-encrypt

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

serde-encrypt logo

🔐 Encrypts all the Serialize.

               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>                    |
+-----------------------------------+        +-----------------------------------+

Overview

serde-encrypt encrypts/decrypts any structs and enums that implements serde::{Serialize, Deserialize}.

serde-encrypt supports both shared-key encryption (XChaCha20-Poly1305) and public-key encryption (XChaCha20-Poly1305 with X25519 key-exchange), both of which are considered to be secure enough.

serde-encrypt is optionally available in no_std environments.

[dependencies]
serde-encrypt = "(version)"  # If you use std
serde-encrypt = {version = "(version)", default-features = false}  # If you need no_std

Example

Good first example from shared key encryption test.

If you and your peer already have shared-key, just implement SerdeEncryptSharedKey trait to your Serialize and Deserialize data types.

#[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).
}

Then, you can serialize the Message into Vec<u8> in encrypted form.

    // 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();

After your peer gets the binary, they can decrypt and deserialize it to 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);

Further examples...

Features and uses cases

Feature comparison

SerdeEncryptSharedKey SerdeEncryptSharedKeyDeterministic SerdeEncryptPublicKey
(a)symmetric? symmetric symmetric asymmetric
deterministic? (*1) no yes no
performance high high low

(*1) Deterministic encryptions always produce the same cipher-text from a given plain-text. More vulnerable but useful for equal-matching in cipher-text (e.g. RDBMS's encrypted index eq-search).

Encryption algorithm

SerdeEncryptSharedKey SerdeEncryptSharedKeyDeterministic SerdeEncryptPublicKey
key exchange - - X25519
encryption XChaCha20 XChaCha20 XChaCha20
message auth Poly1305 Poly1305 Poly1305
nonce (*2) XSalsa20 (random 24-byte) Fixed 24-byte XSalsa20 (random 24-byte)
Rng (*3) for nonce ChaCha20Rng - ChaCha20Rng
Implementation XChaCha20Poly1305 XChaCha20Poly1305 ChaChaBox

(*2) "Number used once": to make encryption non-deterministic. Although nonce for each encryption is not secret, nonce among different encryption must be different in order for attackers to get harder to guess plain-text.

(*3) Random number generator.

Serializer

Crate users can choose and even implement by themselves serialize representations in design.

Currently, the following serializers are built-in.

Use cases

Rust SGX SDK support

Use serde-encrypt-sgx crate.

Feature flags

Implementation

Crates

serde-encrypt is a cargo workspace project and two crates are inside:

serde-encrypt-sgx crate is also available in separate repository. It's in the same layer as serde-encrypt.

In order to use serde with Rust SGX SDK, people should use forked version serde-sgx. Also, Rust SGX SDK compiles with only old version of rustc (nightly-2020-10-25, currently), even simple no_std crate cannot build sometimes (e.g. spin crate cannot).

It is another choice to make serde-encrypt-sgx inside this repository using feature flags but it breaks cargo build --all-features in latest rustc.

Encryption

crypto_box crate is used both for public-key encryption and shared-key encryption.

Pure Rust implementation of the crypto_box public-key authenticated encryption scheme from NaCl-family libraries (e.g. libsodium, TweetNaCl) which combines the X25519 Diffie-Hellman function and the XSalsa20Poly1305 authenticated encryption cipher into an Elliptic Curve Integrated Encryption Scheme (ECIES).

Serialization

structs and enums to encrypt are serialized before encrypted. Built-in serializers are listed here.

Users can also implement TypedSerialized trait by themselves to get better serialization.

Changelog

See CHANGELOG.md.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in serde-encrypt by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.