|
1 | | -//! Module for symmetric/asymmetric encryption/decryption. |
| 1 | +//! Module for chunked, streaming symmetric/asymmetric encryption/decryption. |
2 | 2 | //! |
3 | | -//! This module contains everything related to encryption. You can use it to encrypt and decrypt data using either a shared key of a keypair. |
4 | | -//! Either way, the encryption will give you a `Ciphertext`, which has a method to decrypt it. |
| 3 | +//! Unlike the [`ciphertext`](super::ciphertext) module, which encrypts a whole buffer at |
| 4 | +//! once, this module processes the data one chunk at a time using the STREAM construction. |
| 5 | +//! This lets you encrypt or decrypt data that does not fit in memory, or that arrives |
| 6 | +//! progressively, without ever holding the full plaintext at once. |
| 7 | +//! |
| 8 | +//! You start by creating an `OnlineCiphertextEncryptor`, which produces an |
| 9 | +//! `OnlineCiphertextHeader`. That header is not secret but is required to decrypt: keep it |
| 10 | +//! alongside the ciphertext. You then feed each chunk to `encrypt_next_chunk`, and the final |
| 11 | +//! (possibly smaller) chunk to `encrypt_last_chunk`. Every chunk fed to `encrypt_next_chunk` |
| 12 | +//! must be exactly `chunk_size` bytes; the last chunk may be smaller. Each produced chunk is |
| 13 | +//! `get_tag_size()` bytes larger than its input because of the authentication tag. |
5 | 14 | //! |
6 | 15 | //! ### Symmetric |
7 | 16 | //! |
8 | 17 | //! ```rust |
9 | 18 | //! use devolutions_crypto::utils::generate_key; |
10 | | -//! use devolutions_crypto::ciphertext::{ encrypt, CiphertextVersion, Ciphertext }; |
| 19 | +//! use devolutions_crypto::online_ciphertext::{ |
| 20 | +//! OnlineCiphertextEncryptor, OnlineCiphertextHeader, OnlineCiphertextVersion, |
| 21 | +//! }; |
| 22 | +//! use std::convert::TryFrom; |
11 | 23 | //! |
12 | 24 | //! let key: Vec<u8> = generate_key(32).expect("generate key shouldn't fail"); |
| 25 | +//! let chunk_size = 16u32; |
| 26 | +//! |
| 27 | +//! // Encrypt the data one chunk at a time. |
| 28 | +//! let mut encryptor = |
| 29 | +//! OnlineCiphertextEncryptor::new(&key, b"", chunk_size, OnlineCiphertextVersion::Latest) |
| 30 | +//! .expect("creating the encryptor shouldn't fail"); |
| 31 | +//! |
| 32 | +//! // The header is required to decrypt; store or transmit it alongside the ciphertext. |
| 33 | +//! let header: Vec<u8> = (&encryptor.get_header()).into(); |
13 | 34 | //! |
14 | | -//! let data = b"somesecretdata"; |
| 35 | +//! // Each `_next_chunk` input must be exactly `chunk_size` bytes; the last chunk may be smaller. |
| 36 | +//! let chunk1 = encryptor.encrypt_next_chunk(b"0123456789abcdef", b"").expect("encrypting a chunk shouldn't fail"); |
| 37 | +//! let chunk2 = encryptor.encrypt_last_chunk(b"the last chunk", b"").expect("encrypting the last chunk shouldn't fail"); |
15 | 38 | //! |
16 | | -//! let encrypted_data: Ciphertext = encrypt(data, &key, CiphertextVersion::Latest).expect("encryption shouldn't fail"); |
| 39 | +//! // Decrypt using the header. |
| 40 | +//! let header = OnlineCiphertextHeader::try_from(header.as_slice()).expect("the header should be valid"); |
| 41 | +//! let mut decryptor = header.into_decryptor(&key, b"").expect("creating the decryptor shouldn't fail"); |
17 | 42 | //! |
18 | | -//! let decrypted_data = encrypted_data.decrypt(&key).expect("The decryption shouldn't fail"); |
| 43 | +//! let mut decrypted = decryptor.decrypt_next_chunk(&chunk1, b"").expect("decrypting a chunk shouldn't fail"); |
| 44 | +//! decrypted.extend_from_slice(&decryptor.decrypt_last_chunk(&chunk2, b"").expect("decrypting the last chunk shouldn't fail")); |
19 | 45 | //! |
20 | | -//! assert_eq!(decrypted_data, data); |
| 46 | +//! assert_eq!(decrypted, b"0123456789abcdefthe last chunk"); |
21 | 47 | //! ``` |
22 | 48 | //! |
23 | 49 | //! ### Asymmetric |
24 | 50 | //! Here, you will need a `PublicKey` to encrypt data and the corresponding |
25 | 51 | //! `PrivateKey` to decrypt it. You can generate them by using `generate_keypair` |
26 | | -//! in the [Key module](#key). |
| 52 | +//! in the [Key module](super::key). |
27 | 53 | //! |
28 | 54 | //! ```rust |
29 | 55 | //! use devolutions_crypto::key::{generate_keypair, KeyVersion, KeyPair}; |
30 | | -//! use devolutions_crypto::ciphertext::{ encrypt_asymmetric, CiphertextVersion, Ciphertext }; |
| 56 | +//! use devolutions_crypto::online_ciphertext::{ |
| 57 | +//! OnlineCiphertextEncryptor, OnlineCiphertextHeader, OnlineCiphertextVersion, |
| 58 | +//! }; |
| 59 | +//! use std::convert::TryFrom; |
31 | 60 | //! |
32 | 61 | //! let keypair: KeyPair = generate_keypair(KeyVersion::Latest); |
| 62 | +//! let chunk_size = 16u32; |
| 63 | +//! |
| 64 | +//! let mut encryptor = OnlineCiphertextEncryptor::new_asymmetric( |
| 65 | +//! &keypair.public_key, b"", chunk_size, OnlineCiphertextVersion::Latest, |
| 66 | +//! ).expect("creating the encryptor shouldn't fail"); |
| 67 | +//! |
| 68 | +//! let header: Vec<u8> = (&encryptor.get_header()).into(); |
33 | 69 | //! |
34 | | -//! let data = b"somesecretdata"; |
| 70 | +//! let chunk1 = encryptor.encrypt_next_chunk(b"0123456789abcdef", b"").expect("encrypting a chunk shouldn't fail"); |
| 71 | +//! let chunk2 = encryptor.encrypt_last_chunk(b"the last chunk", b"").expect("encrypting the last chunk shouldn't fail"); |
35 | 72 | //! |
36 | | -//! let encrypted_data: Ciphertext = encrypt_asymmetric(data, &keypair.public_key, CiphertextVersion::Latest).expect("encryption shouldn't fail"); |
| 73 | +//! let header = OnlineCiphertextHeader::try_from(header.as_slice()).expect("the header should be valid"); |
| 74 | +//! let mut decryptor = header.into_decryptor_asymmetric(&keypair.private_key, b"").expect("creating the decryptor shouldn't fail"); |
37 | 75 | //! |
38 | | -//! let decrypted_data = encrypted_data.decrypt_asymmetric(&keypair.private_key).expect("The decryption shouldn't fail"); |
| 76 | +//! let mut decrypted = decryptor.decrypt_next_chunk(&chunk1, b"").expect("decrypting a chunk shouldn't fail"); |
| 77 | +//! decrypted.extend_from_slice(&decryptor.decrypt_last_chunk(&chunk2, b"").expect("decrypting the last chunk shouldn't fail")); |
39 | 78 | //! |
40 | | -//! assert_eq!(decrypted_data, data); |
| 79 | +//! assert_eq!(decrypted, b"0123456789abcdefthe last chunk"); |
41 | 80 | //! ``` |
42 | 81 |
|
43 | 82 | mod online_ciphertext_v1; |
|
0 commit comments