1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
//! Secure symmetric encryption using modern algorithms and affordances.
//!
//! If you want to encrypt something that only someone with the same key can decrypt, and you want
//! the most up-to-date algorithms and security properties (such as Additional Data validation),
//! then StrongBox is for you.
//!
//! A [`StrongBox`] exists to encrypt and decrypt data. It uses a single key to encrypt all
//! data, and can decrypt data that was previously encrypted with any key in the list.
//!
//! The ability to specify a list of decryption keys allows for periodic key rotation, without
//! losing the ability to decrypt old ciphertexts. This is important because *every* symmetric
//! cipher scheme is weakened when many plaintexts (in the "billions" range, so it's *usually* OK)
//! are encrypted with the same key, so it's worth rotating your keys now and then. You simply
//! generate a new key, specify that as your encryption key, and make sure the list of decryption
//! keys includes the new key and all the previous keys that any remaining valid ciphertexts may
//! have been encrypted with.
//!
//! The encryption *context* is used to provide protection against attacks involving
//! substituting one ciphertext for another. [This Security StackExchange
//! answer](https://security.stackexchange.com/a/179279/167630) is an excellent explanation of
//! why an encryption context is useful. If for whatever reason you don't have an appropriate
//! context, you can use `b""` as the context, but remember that the same context must be specified
//! for both encryption *and* decryption.
//!
//! # Other Kinds of StrongBoxes
//!
//! If you have multiple different *kinds* of data to encrypt (say, different fields of a
//! database), it's safer (on many fronts) to encrypt the different kinds of data with different
//! keys. To facilitate that, you can create a [`StemStrongBox`], and "derive" new StrongBoxes
//! that use keys derived from the keys in the [`StemStrongBox`]. This keeps you from having to
//! manage great masses of keys -- instead, just have one set of "root" keys, and derive all the
//! other ones you need. Of course, you can derive another [`StemStrongBox`] from *that* one, and so
//! on, creating a whole "tree" of [`StrongBox`]es.
//!
//! You can also create a [`RotatingStrongBox`], that automatically rotates its keys according to a
//! fixed schedule, and maintains the ability to decrypt ciphertexts encrypted by keys from a
//! bounded number of previous rotations.
//!
//! Finally, there is the [`SharedStrongBox`], which anyone with a public key can use to encrypt
//! data that only someone with the corresponding private key can decrypt.
mod error;
mod rotating_strong_box;
mod shared_strong_box;
mod stem_strong_box;
mod strong_box;
pub use error::Error;
pub use rotating_strong_box::RotatingStrongBox;
pub use shared_strong_box::{SharedStrongBox, SharedStrongBoxKey};
pub use stem_strong_box::StemStrongBox;
pub use strong_box::StrongBox;
use strong_box::Ciphertext;
mod kdf;
mod key_id;
use key_id::{key_id, KeyId};
/// Create a key suitable for use by [`StrongBox`].
///
/// This isn't usually required in real-world usage, as you'll *usually* have your keys
/// stored somewhere out of the way. However, for testing use, or the odd occasion when
/// encryption/decryption is very temporary, a simple function to generate a secure key
/// is useful to have laying around.
#[tracing::instrument(level = "debug")]
pub fn generate_key() -> [u8; 32] {
use rand::{thread_rng, RngCore};
let mut k = [0u8; 32];
thread_rng().fill_bytes(&mut k);
k
}