pub struct StaticStrongBox { /* private fields */ }
Expand description
A secure symmetric encryption container, supporting key rotation and AAD contexts.
This is your basic, Mark 1 mod 0 StrongBox
. Given an encryption key, it will
encrypt data all day long with a modern, fast cipher (ChaCha20) with integrity protection and
authenticated additional data (using Poly1305). If provided with one or more decryption keys,
it will decrypt data that was encrypted with any of those keys, giving you the ability to
“rotate” your key over time, by creating a new key, making it the new encryption key, and
keeping the old key in the set of “decryption” keys until such time as all data has been
re-encrypted with the new key.
The “authenticated additional data” is a mouthful, but what it means is that when you encrypt data, you provide the encryption with a “context”, such as the ID of the user that the encrypted data belongs to. When you decrypt the data again, you provide the ID of the user the data belongs to, and if they don’t match, decryption fails. Why is that useful? Because if an attacker gets write access to the database, and moves encrypted data from one user to another, Bad Things can happen. This Security StackExchange answer is an excellent explanation of why an encryption context is useful.
§Example
use strong_box::{Error, StaticStrongBox, StrongBox};
// A couple of keys are always useful to have
let old_key = strong_box::generate_key();
let new_key = strong_box::generate_key();
let old_strongbox = StaticStrongBox::new(old_key.clone(), [old_key.clone()]);
let new_strongbox = StaticStrongBox::new(new_key.clone(), [new_key.clone()]);
// This StaticStrongBox encrypts with `new_key`, but can decrypt ciphertexts
// encrypted with *either* `new_key` *or* `old_key`
let fallback_strongbox = StaticStrongBox::new(new_key.clone(), vec![new_key, old_key]);
/////////////////////////////////////////////////////////
// A ciphertext encrypted using the old key
let ciphertext = old_strongbox.encrypt(b"Hello, old world!", b"some context")?;
// We'd *hope* that we can decrypt what we encrypted
assert_eq!(
b"Hello, old world!".to_vec(),
old_strongbox.decrypt(&ciphertext, b"some context")?
);
// A StaticStrongBox that uses a different key won't be able to decrypt
let result = new_strongbox.decrypt(&ciphertext, b"some context");
assert!(matches!(result, Err(Error::Decryption)));
// Also, a StaticStrongBox that uses the right key won't decrypt if the context isn't the
// same as was used to encrypt
let result = old_strongbox.decrypt(&ciphertext, b"a different context");
assert!(matches!(result, Err(Error::Decryption)));
// However, magic of magicks, the fallback StaticStrongBox can do the job!
assert_eq!(
b"Hello, old world!".to_vec(),
fallback_strongbox.decrypt(&ciphertext, b"some context")?
);
//////////////////////////////////////////////////////////////
// Now, let's try a ciphertext encrypted using the new key
let ciphertext = new_strongbox.encrypt(b"Hello, new world!", b"new context")?;
// Again, the same StaticStrongBox should be able to decrypt
assert_eq!(
b"Hello, new world!".to_vec(),
new_strongbox.decrypt(&ciphertext, b"new context")?
);
// Unsurprisingly, the fallback StaticStrongBox can decrypt it too, as it uses the same key
assert_eq!(
b"Hello, new world!".to_vec(),
fallback_strongbox.decrypt(&ciphertext, b"new context")?
);
// A StaticStrongBox using just the old key won't be able to decrypt, though
let result = old_strongbox.decrypt(&ciphertext, b"new context");
assert!(matches!(result, Err(Error::Decryption)));
// And again, the right StaticStrongBox but the wrong context won't decrypt
let result = new_strongbox.decrypt(&ciphertext, b"some other context");
assert!(matches!(result, Err(Error::Decryption)));
Implementations§
Source§impl StaticStrongBox
impl StaticStrongBox
Sourcepub fn new(
enc_key: impl Into<Key>,
dec_keys: impl IntoIterator<Item = impl Into<Key>>,
) -> Self
pub fn new( enc_key: impl Into<Key>, dec_keys: impl IntoIterator<Item = impl Into<Key>>, ) -> Self
Create a new StaticStrongBox
.
Trait Implementations§
Source§impl Clone for StaticStrongBox
impl Clone for StaticStrongBox
Source§fn clone(&self) -> StaticStrongBox
fn clone(&self) -> StaticStrongBox
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more