| Crates.io | dcrypt-symmetric |
| lib.rs | dcrypt-symmetric |
| version | 1.2.2 |
| created_at | 2025-07-24 20:44:35.958756+00 |
| updated_at | 2025-12-10 20:22:07.055858+00 |
| description | Symmetric encryption algorithms for the dcrypt library |
| homepage | |
| repository | https://github.com/ioi-foundation/dcrypt |
| max_upload_size | |
| id | 1766905 |
| size | 110,916 |
symmetric)The dcrypt-symmetric crate provides a high-level, secure, and easy-to-use API for common symmetric encryption algorithms within the dcrypt ecosystem. It is built upon the low-level cryptographic primitives in dcrypt-algorithms and integrates with dcrypt-api for a unified and robust error-handling system.
This crate is designed for both ease of use in common scenarios and the flexibility required for more complex applications, such as streaming large files.
Zeroize to securely clear them from memory on drop.dcrypt-api error system for consistent and descriptive error handling across the entire dcrypt library stack.no_std Compatibility: Core features are available in no_std environments.Add the crate to your Cargo.toml file:
[dependencies]
dcrypt-symmetric = "0.12.0-beta.1"
Or add it via the command line:
cargo add dcrypt-symmetric
This example shows a simple encrypt/decrypt cycle using Aes256Gcm.
use dcrypt::symmetric::{Aes256Gcm, Aes256Key, Aead, SymmetricCipher, Result};
fn main() -> Result<()> {
// 1. Generate a new, random key for AES-256-GCM.
let key = Aes256Key::generate();
// 2. Create a new cipher instance.
let cipher = Aes256Gcm::new(&key)?;
// 3. The data to be encrypted.
let plaintext = b"this is a very secret message";
let associated_data = b"metadata"; // Optional associated data
// 4. Generate a random nonce. It MUST be unique for each encryption with the same key.
let nonce = Aes256Gcm::generate_nonce();
// 5. Encrypt the data.
println!("Encrypting: '{}'", String::from_utf8_lossy(plaintext));
let ciphertext = cipher.encrypt(&nonce, plaintext, Some(associated_data))?;
println!("Ciphertext (hex): {}", hex::encode(&ciphertext));
// 6. Decrypt the data.
let decrypted_plaintext = cipher.decrypt(&nonce, &ciphertext, Some(associated_data))?;
println!("Decrypted: '{}'", String::from_utf8_lossy(&decrypted_plaintext));
// 7. Verify the result.
assert_eq!(plaintext, &decrypted_plaintext[..]);
// Decryption will fail if the key, nonce, ciphertext, or AAD is incorrect.
let wrong_key = Aes256Key::generate();
let wrong_cipher = Aes256Gcm::new(&wrong_key)?;
assert!(wrong_cipher.decrypt(&nonce, &ciphertext, Some(associated_data)).is_err());
println!("Decryption with wrong key failed as expected.");
Ok(())
}
The library provides a convenient package format that bundles the nonce with the ciphertext, making it easy to store or transmit.
use dcrypt::symmetric::{
ChaCha20Poly1305Cipher,
ChaCha20Poly1305Key,
ChaCha20Poly1305CiphertextPackage,
SymmetricCipher,
Result
};
fn main() -> Result<()> {
// 1. Generate a key and create a cipher instance.
let (cipher, key) = ChaCha20Poly1305Cipher::generate()?;
let plaintext = b"data packaged for transport";
// 2. Encrypt the data directly into a package.
// This generates a random nonce internally and bundles it with the ciphertext.
let package = cipher.encrypt_to_package(plaintext, None)?;
// 3. The package can be serialized to a string for easy storage or transmission.
let serialized_package = package.to_string();
println!("Serialized Package: {}", serialized_package);
// ... later, on another machine or after retrieving from storage ...
// 4. Create a new cipher instance with the same key.
let receiving_cipher = ChaCha20Poly1305Cipher::new(&key)?;
// 5. Deserialize the package from the string.
let parsed_package = ChaCha20Poly1305CiphertextPackage::from_string(&serialized_package)?;
// 6. Decrypt from the package.
let decrypted_plaintext = receiving_cipher.decrypt_package(&parsed_package, None)?;
println!("Decrypted from package: '{}'", String::from_utf8_lossy(&decrypted_plaintext));
assert_eq!(plaintext, &decrypted_plaintext[..]);
Ok(())
}
Derive a strong cryptographic key from a user-provided password using PBKDF2.
use dcrypt::symmetric::{aes::derive_aes128_key, aes::generate_salt, Result};
fn main() -> Result<()> {
let password = b"a-very-secure-password-123";
// Generate a random salt. The salt should be stored alongside the encrypted data.
let salt = generate_salt(16);
// Set the number of iterations. Higher is more secure but slower.
// OWASP recommends at least 100,000.
let iterations = 250_000;
// Derive a 128-bit key for AES.
let derived_key = derive_aes128_key(password, &salt, iterations)?;
println!("Successfully derived AES-128 key from password.");
// This key can now be used to instantiate an Aes128Gcm cipher.
Ok(())
}
For large files, the streaming API encrypts and decrypts data in chunks, keeping memory usage low. This example uses std::io::Cursor to simulate file I/O.
use std::io::Cursor;
use dcrypt::symmetric::{
streaming::chacha20poly1305::{ChaCha20Poly1305EncryptStream, ChaCha20Poly1305DecryptStream},
streaming::{StreamingEncrypt, StreamingDecrypt},
ChaCha20Poly1305Key,
Result
};
fn main() -> Result<()> {
// 1. Generate a key. In a real app, this would be loaded or derived.
let key = ChaCha20Poly1305Key::generate();
let associated_data = b"streaming-file-example";
// 2. Simulate a large input file and an output buffer for encrypted data.
let source_data = b"This is the first part of a very large file. ".repeat(1000);
let mut source = Cursor::new(source_data);
let mut encrypted_dest = Vec::new();
// 3. Create an encryption stream.
{
let mut encrypt_stream = ChaCha20Poly1305EncryptStream::new(
&mut encrypted_dest,
&key,
Some(associated_data),
)?;
// Pipe data from the source to the encryption stream.
std::io::copy(&mut source, &mut encrypt_stream)?;
} // The stream is finalized when it goes out of scope.
println!("Original size: {} bytes", source.get_ref().len());
println!("Encrypted size: {} bytes", encrypted_dest.len());
// 4. Now, decrypt the data from the stream.
let mut encrypted_source = Cursor::new(encrypted_dest);
let mut decrypt_stream = ChaCha20Poly1305DecryptStream::new(
&mut encrypted_source,
&key,
Some(associated_data),
)?;
// 5. Read the decrypted data back.
let mut decrypted_data = Vec::new();
decrypt_stream.read_to_end(&mut decrypted_data)?;
println!("Decrypted size: {} bytes", decrypted_data.len());
// 6. Verify the integrity of the data.
assert_eq!(source.get_ref(), &decrypted_data);
println!("Successfully encrypted and decrypted stream!");
Ok(())
}
This crate is licensed under the Apache 2.0 License.