DRACOON Crypto utils in Rust
Documentation »
Report Bug
Work in progress Crypto library for DRACOON based on openssl crate.
Breaking changes are most likely at this early stage - the library is under heavy development and depends on requirements from dco3
(currently private API wrapper for DRACOON).
Changes will be documented in the release notes.
- Asymmetric encryption / decryption of file keys (RSA)
- Keypair generation (RSA)
- Keypair encryption / decryption (RSA)
- Symmetric encryption / decryption of messages (AES256 GCM)
- on the fly encryption / decryption
- chunked encryption / decryption
- Refactor asymmetric encryption (split keypair generation from other operations)
- Use other libraries like ring as alternative to openssl bindings
- Add feature flags to cargo build
- Add e2e tests using encryption data from other SDKs / libs and ensure compatibility in pipeline
Using the crate currently binds to the latest openssl version and is compiled in vendored mode (see openssl for details).
See crates.io TL;DR Add the following line to your Cargo.toml file (dependencies):
dco3_crypto = "0.4.1"
Documentation All detailed documentation is provided via docs on docs.rs
The lib consists of several traits that are all (currently only) implemented by the DracoonCrypto
struct.
Therefore, the minimum required import is always DracoonCrypto
and the relevant required trait (DracoonRSACrypto
, Encrypt
, Decrypt
, ChunkedEncryption
, Encrypter
, Decrypter
).
In order to
- generate a (plain) user keypair
- en/decrypt a user keypair
- decrypt a private only
- encrypt a file key with a public key (user keypair)
- decrypt a file key with a private key (user keypair)
Generate a plain user keypair:
use dco3_crypto::{DracoonCrypto, DracoonRSACrypto, UserKeypairVersion};
// RSA2048 is only supported for legacy compatibility
// always use UserKeypairVersion::RSA4096
let new_keypair = DracoonCrypto::create_plain_user_keypair(UserKeyPairVersion::RSA4096).unwrap();
Encrypt a plain user keypair:
use dco3_crypto::{DracoonCrypto, DracoonRSACrypto, UserKeypairVersion};
let new_keypair = DracoonCrypto::create_plain_user_keypair(UserKeyPairVersion::RSA4096).unwrap();
let secret ="VerySecret123!";
let enc_keypair = DracoonCrypto::encrypt_private_key(secret, new_keypair).unwrap();
Decrypt a private key only (for public share use):
use dco3_crypto::{DracoonCrypto, DracoonRSACrypto, UserKeypairVersion};
let new_keypair = DracoonCrypto::create_plain_user_keypair(UserKeyPairVersion::RSA4096).unwrap();
let secret ="VerySecret123!";
let enc_keypair = DracoonCrypto::encrypt_private_key(secret, new_keypair).unwrap();
let plain_private_key = DracoonCrypto::decrypt_private_key_only(secret, enc_keypair.private_key_container).unwrap();
Decrypt a protected user keypair:
use dco3_crypto::{DracoonCrypto, DracoonRSACrypto, UserKeypairVersion};
let new_keypair = DracoonCrypto::create_plain_user_keypair(UserKeyPairVersion::RSA4096).unwrap();
let secret ="VerySecret123!";
let enc_keypair = DracoonCrypto::encrypt_private_key(secret, new_keypair).unwrap();
let plain_keypair = DracoonCrypto::decrypt_private_key(secret, enc_keypair).unwrap();
Encrypt a file key using either a plain user keypair or a public key container:
use dco3_crypto::{DracoonCrypto, DracoonRSACrypto, UserKeypairVersion, Encrypt};
let new_keypair = DracoonCrypto::create_plain_user_keypair(UserKeyPairVersion::RSA4096).unwrap();
// encrypt a message to get a plain file key for demo purposes
let message = b"Secret message";
let (enc_message, plain_file_key) = DracoonCrypto::encrypt(message.to_vec()).unwrap();
// the function also accepts a public key container as argument
let enc_file_key = DracoonCrypto::encrypt_file_key(plain_file_key, plain_keypair).unwrap();
Decrypt the file key using a plain user keypair:
use dco3_crypto::{DracoonCrypto, DracoonRSACrypto, UserKeypairVersion, Encrypt};
let new_keypair = DracoonCrypto::create_plain_user_keypair(UserKeyPairVersion::RSA4096).unwrap();
// encrypt a message to get a plain file key for demo purposes
let message = b"Secret message";
let (enc_message, plain_file_key) = DracoonCrypto::encrypt(message.to_vec()).unwrap();
// the function also accepts a public key container as argument
let enc_file_key = DracoonCrypto::encrypt_file_key(plain_file_key, plain_keypair).unwrap();
// this code is for demo purposes - plain_keypair is consumed above and needs to be
// instantiated again
let plain_file_key = DracoonCrypto::decrypt_file_key(enc_file_key, plain_keypair).unwrap();
Symmetric encryption is represented by the following traits:
- Encrypt: needed for in-memory encryption
- Decrypt: needed for in-memory decryption
- Decrypter: needed to build a decrypter capable of chunked decryption
- Encrypter: needed to build an encrypter capable of chunked encryption
- ChunkedEncryption: needed for both en- and decryption when using a decrypter / encrypter
Encrypt a message on the fly:
use dco3_crypto::{DracoonCrypto, Encrypt};
// encrypt a message to get a plain file key for demo purposes
let message = b"Secret message";
let (enc_message, plain_file_key) = DracoonCrypto::encrypt(message.to_vec()).unwrap();
// to encrypt the file key, see asymmetric encryption above
Decrypt a message on the fly:
use dco3_crypto::{DracoonCrypto, Encrypt, Decrypt};
// encrypt a message to get a plain file key for demo purposes
let message = b"Secret message";
let (enc_message, plain_file_key) = DracoonCrypto::encrypt(message.to_vec()).unwrap();
// to decrypt / encrypt the file key, see asymmetric encryption above
let plain_message = DracoonCrypto::decrypt(&enc_message, plain_file_key);
Encrypt in chunks:
use dco3_crypto::{DracoonCrypto, Encrypter, ChunkedEncryption};
let mut message = b"Encrypt this very long message in chunks and decrypt it";
let buff_len = message.len() 1;
let mut buf = vec![0u8; buff_len];
let mut encrypter = DracoonCrypto::encrypter(&mut buf).unwrap();
let mut count: usize = 0;
// chunks of 8 bytes
const CHUNKSIZE: usize = 8;
let mut chunks = message.chunks(CHUNKSIZE);
while let Some(chunk) = chunks.next() {
count = encrypter.update(&chunk).unwrap();
};
count = encrypter.finalize().unwrap();
let enc_message = encrypter.get_message();
let plain_file_key = encrypter.get_plain_file_key();
Decrypt in chunks:
// importing Encrypt is only necessary for the inital message encryption
use dco3_crypto::{DracoonCrypto, Encrypt, Decrypter, ChunkedEncryption};
use openssl::symm::Cipher;
let message = b"Encrypt this very long message in chunks and decrypt it";
let (message, plain_file_key) = DracoonCrypto::encrypt(message.to_vec()).unwrap();
let buff_len = message.len() 1;
let mut chunks = message.chunks(5);
let mut buf = vec![0u8; buff_len];
let mut decrypter = DracoonCrypto::decrypter(plain_file_key, &mut buf).unwrap();
let mut count: usize = 0;
while let Some(chunk) = chunks.next() {
count = decrypter.update(&chunk).unwrap();
}
count = decrypter.finalize().unwrap();
let plain_message = std::str::from_utf8(decrypter.get_message()).unwrap();