Vitamin C Encrypt
Secure, flexible and fast encryption for Rust types.
This crate is part of the Vitamin C framework to make cryptography code healthy.
Features
- Type-safe encryption: Encrypt and decrypt Rust types with compile-time safety
- AES-256-GCM: Uses AES-256-GCM authenticated encryption via AWS-LC
- 256-bit keys only: Enforces quantum-resistant key sizes for future security
- Protected types integration: Works seamlessly with
vitaminc-protectedfor sensitive data handling - Additional Authenticated Data (AAD): Support for authenticated but unencrypted data
- Automatic nonce generation: Secure random nonce generation for each encryption operation
Installation
Add this to your Cargo.toml:
[]
= "0.1.0-pre4"
= "0.1.0-pre4" # For key generation
Quick Start
use Key;
use ;
// Generate a key
let mut rng = from_entropy;
let key = random.expect;
// Encrypt a message
let ciphertext = encrypt.expect;
// Decrypt it back
let plaintext: String = decrypt.expect;
assert_eq!;
Usage
Key Management
The [Key] type represents a 256-bit encryption key. Vitamin C only supports 256-bit keys to ensure quantum security and compatibility with AWS-LC.
Generating a Key
use Key;
use ;
let mut rng = from_entropy;
let key = random.expect;
Creating a Key from Bytes
use Key;
let key_bytes = ; // In practice, use securely generated bytes
let key = from;
Encrypting Data
The [encrypt] function can encrypt any type that implements the [Encrypt] trait. Built-in support includes:
String&strVec<u8>[u8; N](fixed-size byte arrays)Protected<T>whereTimplementsEncrypt
use ;
use ;
let key = random.expect;
// Encrypt a string
let ciphertext = encrypt.expect;
// Encrypt bytes
let data = vec!;
let ciphertext = encrypt.expect;
// Encrypt a fixed-size array
let array = ;
let ciphertext = encrypt.expect;
Decrypting Data
The [decrypt] function requires you to specify the expected type:
# use ;
# use ;
# let key = random.expect;
// Decrypt to String
let ciphertext = encrypt.expect;
let plaintext: String = decrypt.expect;
// Decrypt to Vec<u8>
let ciphertext = encrypt.expect;
let bytes: = decrypt.expect;
// Decrypt to fixed-size array
let ciphertext = encrypt.expect;
let array: = decrypt.expect;
Additional Authenticated Data (AAD)
AAD allows you to authenticate additional context alongside the ciphertext without encrypting it. This is useful for binding metadata to encrypted data.
use ;
let key = from;
// Encrypt with context
let user_id = "user_123";
let ciphertext = encrypt_with_aad.expect;
// Decrypt with the same context
let plaintext: String = decrypt_with_aad.expect;
assert_eq!;
AAD Must Match
Decryption will fail if the AAD doesn't match:
# use ;
# use Key;
# let key = random.expect;
use ;
// Encrypt with one context
let ciphertext = encrypt_with_aad.expect;
// Try to decrypt with different context - this will fail!
let result: = decrypt_with_aad;
assert!;
Working with Protected Types
Vitamin C Encrypt integrates with vitaminc-protected to ensure sensitive data is handled securely:
use Protected;
use ;
use ;
let key = random.expect;
// Encrypt protected data
let sensitive = new;
let ciphertext = encrypt.expect;
// Decrypt back to protected data
let decrypted: = decrypt.expect;
Encrypting Keys (Key Wrapping)
Keys can be encrypted with other keys, enabling key hierarchy and key wrapping:
use ;
use ;
let mut rng = from_entropy;
// Generate a key encryption key (KEK)
let kek = random.expect;
// Generate a data encryption key (DEK)
let dek = random.expect;
// Wrap the DEK with the KEK
let wrapped_dek = encrypt.expect;
// Later, unwrap the DEK
let unwrapped_dek: Key = decrypt.expect;
Convenience Functions vs Traits
This crate provides both convenience functions and traits:
Convenience functions (recommended for most use cases):
- [
encrypt] - Encrypt with no AAD - [
encrypt_with_aad] - Encrypt with AAD - [
decrypt] - Decrypt with no AAD - [
decrypt_with_aad] - Decrypt with AAD
Traits (for custom implementations):
- [
Encrypt] - Implement to make your types encryptable - [
Decrypt] - Implement to make your types decryptable - [
Cipher] - Implement to create custom cipher algorithms
Example using traits directly:
use ;
let key = from;
let cipher = new.expect;
let ciphertext = "secret".encrypt.expect;
let plaintext: String = Stringdecrypt.expect;
Custom Encryptable Types
You can implement [Encrypt] and [Decrypt] for your own types to enable selective field encryption:
use ;
Security Features
AES-256-GCM
This crate uses AES-256-GCM (Galois/Counter Mode) which provides:
- Confidentiality: Data is encrypted with AES-256
- Authenticity: Built-in authentication prevents tampering
- Performance: Hardware-accelerated on most modern CPUs
AWS-LC
Encryption is powered by AWS-LC, a FIPS-validated cryptographic library maintained by Amazon Web Services.
256-bit Keys Only
Vitamin C enforces 256-bit keys to ensure:
- Resistance to quantum computer attacks (via AES-256)
- Compatibility with AWS-LC's recommended parameters
- No risk of accidentally using weaker key sizes
Automatic Nonce Generation
Each encryption operation generates a unique random nonce, preventing nonce reuse which could compromise security.
Unspecified Errors
Encryption and decryption operations return an [Unspecified] error type that reveals no information about failures. This prevents side-channel attacks that could leak information through error messages.
Best Practices
- Generate keys securely: Always use
Key::random()with a cryptographically secure RNG - Protect keys in memory: The
Keytype usesProtectedinternally to zeroize keys when dropped - Use AAD for context: Include relevant context (user ID, record ID, etc.) as AAD to prevent ciphertext substitution
- Never reuse keys across environments: Use different keys for development, staging, and production
- Rotate keys regularly: Implement key rotation policies for long-lived systems
- Store keys securely: Use key management systems (KMS) for production deployments
Performance
Vitamin C Encrypt is designed for both security and performance:
- Zero-copy operations where possible
- Hardware acceleration via AWS-LC's AES-NI support
- Minimal allocations during encryption/decryption
Error Handling
All encryption operations return Result<T, Unspecified> where [Unspecified] is an opaque error type that reveals no details about the failure. This is intentional to prevent side-channel attacks.
use ;
use ;
let key = random.expect;
match encrypt
CipherStash
Vitamin C is brought to you by the team at CipherStash.
License: MIT