Expand description
§Bitwarden Cryptographic primitives
This crate contains the cryptographic primitives used throughout the SDK. The general aspiration is for this crate to handle all the difficult cryptographic operations and expose higher level concepts to the rest of the SDK.
Generally you should not find yourself needing to edit this crate! Everything written
here requires additional care and attention to ensure that the cryptographic primitives are
secure.
§Example:
use bitwarden_crypto::{SymmetricCryptoKey, KeyEncryptable, KeyDecryptable, CryptoError};
async fn example() -> Result<(), CryptoError> {
let key = SymmetricCryptoKey::generate(rand::thread_rng());
let data = "Hello, World!".to_owned();
let encrypted = data.clone().encrypt_with_key(&key)?;
let decrypted: String = encrypted.decrypt_with_key(&key)?;
assert_eq!(data, decrypted);
Ok(())
}
§Development considerations
This crate is expected to provide long term support for cryptographic operations. To that end, the following considerations should be taken into account when making changes to this crate:
- Limit public interfaces to the bare minimum.
- Breaking changes should be rare and well communicated.
- Serializable representation of keys and encrypted data must be supported indefinitely as we have no way to update all data.
§Conventions:
- Pure Functions that deterministically “derive” keys from input are prefixed with
derive_
. - Functions that generate non deterministically keys are prefixed with
make_
.
§Differences from clients
There are some noteworthy differences compared to the other Bitwarden clients. These changes are made in an effort to introduce conventions in how we name things, improve best practices and abstracting away internal complexity.
CryptoService.makeSendKey
&AccessService.createAccessToken
are replaced by the genericderive_shareable_key
- MasterKey operations such as
makeMasterKey
andhashMasterKey
are moved to the MasterKey struct.
§Crate features
no-memory-hardening
- Disables memory hardening which ensures that allocated memory is zeroed on drop. This feature primarily exists in case you do not want to use the standard allocator, and we advise to still define aglobal_allocator
using theZeroizingAllocator
.
Modules§
- aes 🔒AES operations
- Encrypted string types
- error 🔒
- Fingerprint
- keys 🔒
- rsa 🔒
- store 🔒This module contains all the necessary parts to create an in-memory key store that can be used to securely store key and use them for encryption/decryption operations.
- traits 🔒
- util 🔒
- wordlist 🔒
Macros§
- Just a small derive_like macro that can be used to generate the key identifier enums. Example usage:
Structs§
- An asymmetric encryption key. Contains both the public and private key. Can be used to both encrypt and decrypt
AsymmetricEncString
. - An asymmetric public encryption key. Can only encrypt AsymmetricEncString, usually accompanied by a AsymmetricCryptoKey
- Device Key
- An in-memory key store that provides a safe and secure way to store keys and use them for encryption/decryption operations. The store API is designed to work only on key identifiers (KeyId). These identifiers are user-defined types that contain no key material, which means the API users don’t have to worry about accidentally leaking keys.
- The context of a crypto operation using super::KeyStore
- Master Key.
- Pin Key.
- RSA Key Pair
- A symmetric encryption key. Used to encrypt and decrypt
EncString
- User Key
- Allocator wrapper that zeros on free
Enums§
- Encrypted string primitive
- Encrypted string primitive
- Key Derivation Function for Bitwarden Account
Constants§
- EFF’s Long Wordlist from https://www.eff.org/dice
- Export namespace metadata.
Traits§
- Trait to allow both
AsymmetricCryptoKey
andAsymmetricPublicCryptoKey
to be used to encrypt AsymmetricEncString. - A decryption operation that takes the input value and decrypts it into the output value. Implementations should generally consist of calling Decryptable::decrypt for all the fields of the type.
- An encryption operation that takes the input value and encrypts it into the output value. Implementations should generally consist of calling Encryptable::encrypt for all the fields of the type.
- Types implementing IdentifyKey are capable of knowing which cryptographic key is needed to encrypt/decrypt them.
- Represents a key identifier that can be used to identify cryptographic keys in the key store. It is used to avoid exposing the key material directly in the public API.
- Represents a set of all the key identifiers that need to be defined to use a key store. At the moment it’s just symmetric and asymmetric keys.
Functions§
- Default Argon2 iterations
- Default Argon2 memory
- Default Argon2 parallelism
- Default PBKDF2 iterations
- Derive a shareable key using hkdf from secret and name.
- Computes a fingerprint of the given
fingerprint_material
using the givenpublic_key
. - Generate a random alphanumeric string of a given length
- Generate random bytes that are cryptographically secure
- Derive pbkdf2 of a given password and salt