🎯 empfohlene Sammlungen
Balanced sample collections from various categories for you to explore
Web Rust Kryptographiebeispiele
Web Rust Kryptographiebeispiele einschließlich Hash-Berechnung, symmetrischer Verschlüsselung und Base64-Codierung
💻 Hash-Berechnung rust
🟢 simple
⭐⭐
MD5-, SHA-1-, SHA-256- und SHA-512-Hashes mit sha2 und md5 crates berechnen
⏱️ 20 min
🏷️ rust, web, cryptography
Prerequisites:
Basic Rust, sha2 crate, md5 crate
// Web Rust Hash Calculation Examples
// Calculate various hash values for data integrity and security
//
// Add to Cargo.toml:
// [dependencies]
// sha2 = "0.10"
// md5 = "0.7"
// hex = "0.4"
use sha2::{Sha256, Sha512, Digest};
use md5::{Md5 as Md5Hash};
// 1. MD5 Hash
/// Calculate MD5 hash of string
fn calculate_md5_string(input: &str) -> String {
let mut hasher = Md5Hash::new();
hasher.update(input.as_bytes());
let result = hasher.finalize();
format!("{:x}", result)
}
/// Calculate MD5 hash of bytes
fn calculate_md5_bytes(data: &[u8]) -> String {
let mut hasher = Md5Hash::new();
hasher.update(data);
let result = hasher.finalize();
format!("{:x}", result)
}
// 2. SHA-1 Hash (using sha2)
/// Calculate SHA-1 hash
fn calculate_sha1(input: &str) -> String {
use sha2::Sha1;
let mut hasher = Sha1::new();
hasher.update(input.as_bytes());
let result = hasher.finalize();
format!("{:x}", result)
}
// 3. SHA-256 Hash
/// Calculate SHA-256 hash of string
fn calculate_sha256_string(input: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(input.as_bytes());
let result = hasher.finalize();
format!("{:x}", result)
}
/// Calculate SHA-256 hash of bytes
fn calculate_sha256_bytes(data: &[u8]) -> String {
let mut hasher = Sha256::new();
hasher.update(data);
let result = hasher.finalize();
format!("{:x}", result)
}
/// Calculate SHA-256 hash of file
fn calculate_sha256_file(path: &str) -> Result<String, std::io::Error> {
use std::io::Read;
let mut file = std::fs::File::open(path)?;
let mut hasher = Sha256::new();
let mut buffer = [0u8; 8192];
loop {
let n = file.read(&mut buffer)?;
if n == 0 {
break;
}
hasher.update(&buffer[..n]);
}
Ok(format!("{:x}", hasher.finalize()))
}
// 4. SHA-512 Hash
/// Calculate SHA-512 hash of string
fn calculate_sha512_string(input: &str) -> String {
let mut hasher = Sha512::new();
hasher.update(input.as_bytes());
let result = hasher.finalize();
format!("{:x}", result)
}
/// Calculate SHA-512 hash of bytes
fn calculate_sha512_bytes(data: &[u8]) -> String {
let mut hasher = Sha512::new();
hasher.update(data);
let result = hasher.finalize();
format!("{:x}", result)
}
// 5. Hash with Salt
/// Hash password with salt using SHA-256
fn hash_password_with_salt(password: &str, salt: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(password.as_bytes());
hasher.update(salt.as_bytes());
let result = hasher.finalize();
format!("{:x}", result)
}
/// Generate random salt
fn generate_salt() -> String {
use rand::Rng;
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789";
let mut rng = rand::thread_rng();
(0..32)
.map(|_| {
let idx = rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect()
}
/// Hash password with auto-generated salt
fn hash_password(password: &str) -> (String, String) {
let salt = generate_salt();
let hash = hash_password_with_salt(password, &salt);
(hash, salt)
}
// 6. Hash Verification
/// Verify password against hash
fn verify_password(password: &str, salt: &str, hash: &str) -> bool {
let computed_hash = hash_password_with_salt(password, salt);
computed_hash == hash
}
// 7. Multiple Hashing (Iterated)
/// Hash with multiple iterations (key stretching)
fn hash_iterations(data: &str, iterations: usize) -> String {
let mut current = data.to_string();
for _ in 0..iterations {
current = calculate_sha256_string(¤t);
}
current
}
// 8. HMAC (Hash-based Message Authentication Code)
/// Calculate HMAC-SHA256
fn calculate_hmac_sha256(message: &str, key: &str) -> String {
use hmac::{Hmac, Mac};
type HmacSha256 = Hmac<Sha256>;
let mut mac = HmacSha256::new_from_slice(key.as_bytes()).expect("HMAC key length error");
mac.update(message.as_bytes());
let result = mac.finalize();
format!("{:x}", result.into_bytes())
}
// 9. Hash Comparison
/// Constant-time hash comparison to prevent timing attacks
fn hash_equals(hash1: &str, hash2: &str) -> bool {
use subtle::ConstantTimeEq;
hash1.as_bytes().ct_eq(hash2.as_bytes()).into()
}
// 10. Checksum
/// Calculate simple checksum
fn calculate_checksum(data: &[u8]) -> u8 {
data.iter().fold(0u8, |acc, &b| acc.wrapping_add(b))
}
/// Calculate CRC32 checksum
fn calculate_crc32(data: &[u8]) -> u32 {
let mut crc: u32 = 0xFFFFFFFF;
for &byte in data {
crc ^= byte as u32;
for _ in 0..8 {
if crc & 1 != 0 {
crc = (crc >> 1) ^ 0xEDB88320;
} else {
crc >>= 1;
}
}
}
!crc
}
// 11. Batch Hashing
/// Hash multiple strings
fn hash_multiple_strings(strings: &[&str]) -> Vec<String> {
strings.iter()
.map(|s| calculate_sha256_string(s))
.collect()
}
/// Find hash collisions (simple check)
fn find_hash_collisions(strings: &[&str]) -> Vec<(String, String, String)> {
use std::collections::HashMap;
let mut hash_map: HashMap<String, Vec<&str>> = HashMap::new();
for &s in strings {
let hash = calculate_sha256_string(s);
hash_map.entry(hash).or_insert_with(Vec::new).push(s);
}
hash_map.into_iter()
.filter(|(_, v)| v.len() > 1)
.flat_map(|(hash, strings)| {
strings.iter().map(move |s| (s.to_string(), hash.clone()))
})
.collect::<Vec<_>>()
.chunks(2)
.map(|c| {
if c.len() == 2 {
(c[0].0.clone(), c[1].0.clone(), c[0].1.clone())
} else {
(String::new(), String::new(), String::new())
}
})
.collect()
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust Hash Calculation Examples ===\n");
let test_string = "Hello, World!";
let test_bytes = b"Hello, World!";
// 1. MD5
println!("--- 1. MD5 Hash ---");
println!("MD5 of '{}': {}", test_string, calculate_md5_string(test_string));
println!("MD5 of bytes: {}", calculate_md5_bytes(test_bytes));
// 2. SHA-1
println!("\n--- 2. SHA-1 Hash ---");
println!("SHA-1 of '{}': {}", test_string, calculate_sha1(test_string));
// 3. SHA-256
println!("\n--- 3. SHA-256 Hash ---");
println!("SHA-256 of '{}': {}", test_string, calculate_sha256_string(test_string));
println!("SHA-256 of bytes: {}", calculate_sha256_bytes(test_bytes));
// 4. SHA-512
println!("\n--- 4. SHA-512 Hash ---");
println!("SHA-512 of '{}': {}", test_string, calculate_sha512_string(test_string));
println!("SHA-512 of bytes: {}", calculate_sha512_bytes(test_bytes));
// 5. Password hashing with salt
println!("\n--- 5. Password Hashing with Salt ---");
let password = "secure_password_123";
let (hash, salt) = hash_password(password);
println!("Password: {}", password);
println!("Salt: {}", salt);
println!("Hash: {}", hash);
// 6. Verify password
println!("\n--- 6. Verify Password ---");
let is_valid = verify_password(password, &salt, &hash);
println!("Password verification: {}", is_valid);
let is_invalid = verify_password("wrong_password", &salt, &hash);
println!("Wrong password verification: {}", is_invalid);
// 7. Iterated hashing
println!("\n--- 7. Iterated Hashing ---");
let iterated = hash_iterations(test_string, 1000);
println!("Hash after 1000 iterations: {}", iterated);
// 8. HMAC
println!("\n--- 8. HMAC-SHA256 ---");
let message = "Important message";
let key = "secret_key";
let hmac = calculate_hmac_sha256(message, key);
println!("HMAC of '{}' with key '{}': {}", message, key, hmac);
// 9. Hash comparison
println!("\n--- 9. Hash Comparison ---");
let hash1 = calculate_sha256_string("test");
let hash2 = calculate_sha256_string("test");
let hash3 = calculate_sha256_string("different");
println!("hash1 vs hash2: {}", hash_equals(&hash1, &hash2));
println!("hash1 vs hash3: {}", hash_equals(&hash1, &hash3));
// 10. Checksums
println!("\n--- 10. Checksums ---");
let checksum = calculate_checksum(test_bytes);
println!("Simple checksum: {}", checksum);
let crc32 = calculate_crc32(test_bytes);
println!("CRC32: {:08x}", crc32);
// 11. Batch hashing
println!("\n--- 11. Batch Hashing ---");
let strings = vec!["hello", "world", "rust"];
let hashes = hash_multiple_strings(&strings);
for (s, h) in strings.iter().zip(hashes.iter()) {
println!("SHA256 of '{}': {}", s, h);
}
println!("\n=== All Hash Calculation Examples Completed ===");
Ok(())
}
💻 Base64-Codierung rust
🟢 simple
⭐⭐
Daten mit Base64-Codierung mit Standard- und URL-sicheren Varianten codieren und decodieren
⏱️ 15 min
🏷️ rust, web, cryptography
Prerequisites:
Basic Rust, base64 crate
// Web Rust Base64 Encoding Examples
// Base64 encoding and decoding operations
//
// Add to Cargo.toml:
// [dependencies]
// base64 = "0.21"
use base64::{Engine as _, engine::general_purpose};
// 1. Standard Base64 Encoding
/// Encode bytes to standard Base64
fn encode_base64(data: &[u8]) -> String {
general_purpose::STANDARD.encode(data)
}
/// Decode Base64 to bytes
fn decode_base64(encoded: &str) -> Result<Vec<u8>, base64::DecodeError> {
general_purpose::STANDARD.decode(encoded)
}
/// Encode string to Base64
fn encode_string_base64(input: &str) -> String {
encode_base64(input.as_bytes())
}
// 2. URL-Safe Base64 Encoding
/// Encode bytes to URL-safe Base64
fn encode_base64_url_safe(data: &[u8]) -> String {
general_purpose::URL_SAFE.encode(data)
}
/// Decode URL-safe Base64
fn decode_base64_url_safe(encoded: &str) -> Result<Vec<u8>, base64::DecodeError> {
general_purpose::URL_SAFE.decode(encoded)
}
// 3. Base64 without Padding
/// Encode without padding (no '=' characters)
fn encode_base64_no_pad(data: &[u8]) -> String {
general_purpose::STANDARD_NO_PAD.encode(data)
}
/// Decode Base64 without padding
fn decode_base64_no_pad(encoded: &str) -> Result<Vec<u8>, base64::DecodeError> {
general_purpose::STANDARD_NO_PAD.decode(encoded)
}
// 4. Base64 with Custom Configuration
/// Encode with custom configuration
fn encode_base64_custom(data: &[u8], url_safe: bool, pad: bool) -> String {
use base64::engine::Config;
let config = Config::new()
.with_encode_padding(pad);
if url_safe {
base64::engine::GeneralPurpose::new(
&base64::alphabet::URL_SAFE,
config
).encode(data)
} else {
base64::engine::GeneralPurpose::new(
&base64::alphabet::STANDARD,
config
).encode(data)
}
}
// 5. Binary Data Encoding
/// Encode binary file to Base64
fn encode_file_to_base64(path: &str) -> Result<String, std::io::Error> {
use std::io::Read;
let mut file = std::fs::File::open(path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
Ok(encode_base64(&buffer))
}
/// Decode Base64 and write to file
fn decode_base64_to_file(encoded: &str, output_path: &str) -> Result<(), std::io::Error> {
use std::io::Write;
let decoded = decode_base64(encoded)?;
let mut file = std::fs::File::create(output_path)?;
file.write_all(&decoded)?;
Ok(())
}
// 6. Stream Encoding
/// Encode data in chunks
fn encode_chunks(data: &[u8], chunk_size: usize) -> Vec<String> {
data.chunks(chunk_size)
.map(|chunk| encode_base64(chunk))
.collect()
}
/// Decode multiple Base64 strings
fn decode_multiple(encoded_strings: &[&str]) -> Result<Vec<u8>, base64::DecodeError> {
let mut result = Vec::new();
for encoded in encoded_strings {
result.extend(decode_base64(encoded)?);
}
Ok(result)
}
// 7. Base64 for URLs
/// Encode data for use in URL parameters
fn encode_for_url(data: &[u8]) -> String {
// Remove padding and use URL-safe alphabet
let encoded = encode_base64_url_safe(data);
encoded.trim_end_matches('=').to_string()
}
/// Decode URL parameter
fn decode_from_url(encoded: &str) -> Result<Vec<u8>, base64::DecodeError> {
// Add padding back if needed
let padded = if encoded.len() % 4 != 0 {
let padding = 4 - (encoded.len() % 4);
format!("{}{}", encoded, "=".repeat(padding))
} else {
encoded.to_string()
};
decode_base64_url_safe(&padded)
}
// 8. Validation
/// Check if string is valid Base64
fn is_valid_base64(s: &str) -> bool {
decode_base64(s).is_ok()
}
/// Check if string is valid URL-safe Base64
fn is_valid_base64_url(s: &str) -> bool {
decode_base64_url_safe(s).is_ok()
}
// 9. Base64 Length Calculation
/// Calculate encoded length from data length
fn calculate_encoded_length(data_len: usize, with_padding: bool) -> usize {
let encoded_len = ((data_len + 2) / 3) * 4;
if with_padding {
encoded_len
} else {
encoded_len - (data_len % 3).min(2)
}
}
/// Calculate decoded length from encoded string
fn calculate_decoded_length(encoded_len: usize) -> usize {
(encoded_len * 3) / 4
}
// 10. Hash Encoding
/// Encode binary hash to Base64 for display
fn encode_hash_to_base64(hash: &[u8]) -> String {
encode_base64(hash)
}
/// Create Base64-encoded SHA256 hash
fn hash_and_encode_base64(data: &[u8]) -> String {
use sha2::{Sha256, Digest};
let mut hasher = Sha256::new();
hasher.update(data);
let hash = hasher.finalize();
encode_base64(&hash)
}
// 11. Comparison
/// Compare two Base64 strings (constant-time)
fn base64_equals(encoded1: &str, encoded2: &str) -> Result<bool, base64::DecodeError> {
use subtle::ConstantTimeEq;
let bytes1 = decode_base64(encoded1)?;
let bytes2 = decode_base64(encoded2)?;
Ok(bytes1.ct_eq(&bytes2).into())
}
// 12. Common Use Cases
/// Encode credentials for Basic Auth
fn encode_basic_auth(username: &str, password: &str) -> String {
let credentials = format!("{}:{}", username, password);
encode_string_base64(&credentials)
}
/// Encode JSON for URL transmission
fn encode_json_for_url<T: serde::Serialize>(data: &T) -> Result<String, Box<dyn std::error::Error>> {
let json = serde_json::to_string(data)?;
Ok(encode_for_url(json.as_bytes()))
}
/// Decode JSON from URL transmission
fn decode_json_from_url<T: for<'de> serde::Deserialize<'de>>(
encoded: &str
) -> Result<T, Box<dyn std::error::Error>> {
let decoded = decode_from_url(encoded)?;
let json_str = String::from_utf8(decoded)?;
let data = serde_json::from_str(&json_str)?;
Ok(data)
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust Base64 Encoding Examples ===\n");
let test_data = b"Hello, World!";
let test_string = "Hello, Base64!";
// 1. Standard encoding
println!("--- 1. Standard Base64 Encoding ---");
let encoded = encode_base64(test_data);
println!("Encoded: {}", encoded);
let decoded = decode_base64(&encoded)?;
println!("Decoded: {}", String::from_utf8(decoded)?);
// 2. String encoding
println!("\n--- 2. String Encoding ---");
let encoded_str = encode_string_base64(test_string);
println!("Encoded string: {}", encoded_str);
// 3. URL-safe encoding
println!("\n--- 3. URL-Safe Encoding ---");
let url_data = b"data with/slashes+and=equals";
let url_encoded = encode_base64_url_safe(url_data);
println!("URL-safe encoded: {}", url_encoded);
let url_decoded = decode_base64_url_safe(&url_encoded)?;
println!("URL-safe decoded: {}", String::from_utf8(url_decoded)?);
// 4. No padding
println!("\n--- 4. Encoding Without Padding ---");
let no_pad = encode_base64_no_pad(test_data);
println!("No padding: {}", no_pad);
println!("Standard: {}", encoded);
// 5. Chunked encoding
println!("\n--- 5. Chunked Encoding ---");
let large_data = b"This is a longer piece of data that will be encoded in chunks";
let chunks = encode_chunks(large_data, 10);
println!("Encoded in {} chunks:", chunks.len());
for (i, chunk) in chunks.iter().enumerate() {
println!(" Chunk {}: {}", i + 1, chunk);
}
// 6. URL encoding
println!("\n--- 6. URL Encoding ---");
let url_safe_data = b"safe for url";
let url_encoded_data = encode_for_url(url_safe_data);
println!("URL encoded: {}", url_encoded_data);
let url_decoded_data = decode_from_url(&url_encoded_data)?;
println!("URL decoded: {}", String::from_utf8(url_decoded_data)?);
// 7. Validation
println!("\n--- 7. Validation ---");
println!("Is valid Base64: {}", is_valid_base64(&encoded));
println!("Is invalid valid: {}", !is_valid_base64("invalid@base64!"));
// 8. Length calculations
println!("\n--- 8. Length Calculations ---");
let data_len = test_data.len();
println!("Original length: {}", data_len);
println!("Encoded length (with padding): {}", calculate_encoded_length(data_len, true));
println!("Encoded length (no padding): {}", calculate_encoded_length(data_len, false));
println!("Actual encoded length: {}", encoded.len());
// 9. Hash encoding
println!("\n--- 9. Hash Encoding ---");
let hash_encoded = hash_and_encode_base64(test_data);
println!("SHA256 as Base64: {}", hash_encoded);
// 10. Basic auth
println!("\n--- 10. Basic Auth ---");
let auth = encode_basic_auth("alice", "secret123");
println!("Basic auth header: Basic {}", auth);
// 11. JSON in URL
println!("\n--- 11. JSON URL Encoding ---");
#[derive(serde::Serialize, Deserialize, Debug)]
struct Data {
name: String,
value: i32,
}
let json_data = Data {
name: "Test".to_string(),
value: 42,
};
let json_encoded = encode_json_for_url(&json_data)?;
println!("JSON URL encoded: {}", json_encoded);
let json_decoded: Data = decode_json_from_url(&json_encoded)?;
println!("JSON decoded: {:?}", json_decoded);
// 12. Comparison
println!("\n--- 12. Base64 Comparison ---");
let encoded1 = encode_base64(b"test");
let encoded2 = encode_base64(b"test");
let encoded3 = encode_base64(b"different");
println!("encoded1 == encoded2: {}", base64_equals(&encoded1, &encoded2)?);
println!("encoded1 == encoded3: {}", base64_equals(&encoded1, &encoded3)?);
println!("\n=== All Base64 Encoding Examples Completed ===");
Ok(())
}
💻 Symmetrische Verschlüsselung rust
🟡 intermediate
⭐⭐⭐⭐
Daten mit AES im GCM-Modus verschlüsseln und entschlüsseln
⏱️ 30 min
🏷️ rust, web, cryptography, encryption
Prerequisites:
Intermediate Rust, aes-gcm crate
// Web Rust Symmetric Encryption Examples
// AES encryption and decryption with GCM mode
//
// Add to Cargo.toml:
// [dependencies]
// aes-gcm = "0.10"
// rand = "0.8"
// hex = "0.4"
use aes_gcm::{
Aes256Gcm,
Key,
Nonce,
aead::{Aead, AeadCore, KeyInit, OsRng},
};
use rand::Rng;
// 1. Key Generation
/// Generate random 256-bit key for AES-256
fn generate_key() -> [u8; 32] {
Aes256Gcm::generate_key().into()
}
/// Generate key from password using PBKDF2
fn key_from_password(password: &str, salt: &[u8; 32], iterations: u32) -> [u8; 32] {
use pbkdf2::pbkdf2_hmac;
use sha2::Sha256;
let mut key_bytes = [0u8; 32];
pbkdf2_hmac::<Sha256>(
password.as_bytes(),
salt,
iterations,
&mut key_bytes,
);
key_bytes
}
// 2. Nonce Generation
/// Generate random nonce for AES-GCM
fn generate_nonce() -> [u8; 12] {
Aes256Gcm::generate_nonce().into()
}
/// Create nonce from counter (for testing)
fn nonce_from_counter(counter: u64) -> [u8; 12] {
let mut nonce = [0u8; 12];
nonce[4..].copy_from_slice(&counter.to_be_bytes());
nonce
}
// 3. AES-GCM Encryption
/// Encrypt data using AES-256-GCM
fn encrypt_aes256_gcm(
key: &[u8; 32],
nonce: &[u8; 12],
plaintext: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce = Nonce::from_slice(nonce);
let ciphertext = cipher.encrypt(nonce, plaintext)?;
Ok(ciphertext)
}
/// Encrypt string using AES-256-GCM
fn encrypt_string_aes256_gcm(
key: &[u8; 32],
nonce: &[u8; 12],
plaintext: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let ciphertext = encrypt_aes256_gcm(key, nonce, plaintext.as_bytes())?;
Ok(hex::encode(ciphertext))
}
// 4. AES-GCM Decryption
/// Decrypt data using AES-256-GCM
fn decrypt_aes256_gcm(
key: &[u8; 32],
nonce: &[u8; 12],
ciphertext: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce = Nonce::from_slice(nonce);
let plaintext = cipher.decrypt(nonce, ciphertext)?;
Ok(plaintext)
}
/// Decrypt hex-encoded string using AES-256-GCM
fn decrypt_string_aes256_gcm(
key: &[u8; 32],
nonce: &[u8; 12],
ciphertext_hex: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let ciphertext = hex::decode(ciphertext_hex)?;
let plaintext_bytes = decrypt_aes256_gcm(key, nonce, &ciphertext)?;
Ok(String::from_utf8(plaintext_bytes)?)
}
// 5. Encryption with Associated Data (AAD)
/// Encrypt with additional authenticated data
fn encrypt_with_aad(
key: &[u8; 32],
nonce: &[u8; 12],
plaintext: &[u8],
aad: &[u8],
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce = Nonce::from_slice(nonce);
let ciphertext = cipher.encrypt(nonce, plaintext)?;
Ok(ciphertext)
}
// 6. Complete Encryption Structure
/// Encrypted message with nonce
#[derive(Debug)]
struct EncryptedMessage {
nonce: [u8; 12],
ciphertext: Vec<u8>,
}
/// Encrypt and return message with nonce
fn encrypt_message(key: &[u8; 32], plaintext: &str) -> EncryptedMessage {
let nonce = generate_nonce();
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce_obj = Nonce::from_slice(&nonce);
let ciphertext = cipher.encrypt(nonce_obj, plaintext.as_bytes()).unwrap();
EncryptedMessage { nonce, ciphertext }
}
/// Decrypt message with embedded nonce
fn decrypt_message(key: &[u8; 32], message: EncryptedMessage) -> Result<String, Box<dyn std::error::Error>> {
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce = Nonce::from_slice(&message.nonce);
let plaintext = cipher.decrypt(nonce, message.ciphertext.as_slice())?;
Ok(String::from_utf8(plaintext)?)
}
// 7. File Encryption
/// Encrypt file contents
fn encrypt_file(
key: &[u8; 32],
input_path: &str,
output_path: &str,
) -> Result<(), Box<dyn std::error::Error>> {
use std::io::Read;
use std::io::Write;
// Read input file
let mut file = std::fs::File::open(input_path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
// Encrypt
let nonce = generate_nonce();
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce_obj = Nonce::from_slice(&nonce);
let ciphertext = cipher.encrypt(nonce_obj, buffer.as_slice())?;
// Write nonce + ciphertext to output
let mut output = std::fs::File::create(output_path)?;
output.write_all(&nonce)?;
output.write_all(&ciphertext)?;
Ok(())
}
/// Decrypt file contents
fn decrypt_file(
key: &[u8; 32],
input_path: &str,
output_path: &str,
) -> Result<(), Box<dyn std::error::Error>> {
use std::io::Read;
use std::io::Write;
// Read input file
let mut file = std::fs::File::open(input_path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
// Extract nonce (first 12 bytes)
let mut nonce = [0u8; 12];
nonce.copy_from_slice(&buffer[..12]);
let ciphertext = &buffer[12..];
// Decrypt
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce_obj = Nonce::from_slice(&nonce);
let plaintext = cipher.decrypt(nonce_obj, ciphertext)?;
// Write to output
let mut output = std::fs::File::create(output_path)?;
output.write_all(&plaintext)?;
Ok(())
}
// 8. Stream Encryption (Chunked)
/// Encrypt data in chunks
fn encrypt_chunked(
key: &[u8; 32],
data: &[u8],
chunk_size: usize,
) -> Result<Vec<(Vec<u8>, [u8; 12])>, Box<dyn std::error::Error>> {
let mut results = Vec::new();
for chunk in data.chunks(chunk_size) {
let nonce = generate_nonce();
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
let nonce_obj = Nonce::from_slice(&nonce);
let ciphertext = cipher.encrypt(nonce_obj, chunk)?;
results.push((ciphertext, nonce));
}
Ok(results)
}
// 9. Key Derivation
/// Derive encryption key from passphrase
struct EncryptionKey {
key: [u8; 32],
salt: [u8; 32],
}
impl EncryptionKey {
fn new(passphrase: &str) -> Self {
let mut salt = [0u8; 32];
let mut rng = rand::thread_rng();
rng.fill(&mut salt);
let key = key_from_password(passphrase, &salt, 100_000);
EncryptionKey { key, salt }
}
fn from_salt(passphrase: &str, salt: [u8; 32]) -> Self {
let key = key_from_password(passphrase, &salt, 100_000);
EncryptionKey { key, salt }
}
}
// 10. Password-Based Encryption
/// Encrypt with password
fn encrypt_with_password(
password: &str,
plaintext: &str,
) -> Result<(String, [u8; 32], [u8; 12]), Box<dyn std::error::Error>> {
let enc_key = EncryptionKey::new(password);
let nonce = generate_nonce();
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&enc_key.key));
let nonce_obj = Nonce::from_slice(&nonce);
let ciphertext = cipher.encrypt(nonce_obj, plaintext.as_bytes())?;
Ok((hex::encode(ciphertext), enc_key.salt, nonce))
}
/// Decrypt with password
fn decrypt_with_password(
password: &str,
ciphertext_hex: &str,
salt: [u8; 32],
nonce: [u8; 12],
) -> Result<String, Box<dyn std::error::Error>> {
let enc_key = EncryptionKey::from_salt(password, salt);
let ciphertext = hex::decode(ciphertext_hex)?;
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&enc_key.key));
let nonce_obj = Nonce::from_slice(&nonce);
let plaintext = cipher.decrypt(nonce_obj, ciphertext.as_slice())?;
Ok(String::from_utf8(plaintext)?)
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust Symmetric Encryption Examples ===\n");
// 1. Generate key
println!("--- 1. Key Generation ---");
let key = generate_key();
println!("Generated key: {}", hex::encode(key));
// 2. Generate nonce
println!("\n--- 2. Nonce Generation ---");
let nonce = generate_nonce();
println!("Generated nonce: {}", hex::encode(nonce));
// 3. Encrypt string
println!("\n--- 3. Encrypt String ---");
let plaintext = "Secret message!";
let encrypted = encrypt_string_aes256_gcm(&key, &nonce, plaintext)?;
println!("Plaintext: {}", plaintext);
println!("Encrypted: {}", encrypted);
// 4. Decrypt string
println!("\n--- 4. Decrypt String ---");
let decrypted = decrypt_string_aes256_gcm(&key, &nonce, &encrypted)?;
println!("Decrypted: {}", decrypted);
// 5. Complete message encryption
println!("\n--- 5. Complete Message ---");
let message = encrypt_message(&key, "Hello, secure world!");
println!("Encrypted message: {:?}", message);
let decrypted_msg = decrypt_message(&key, message)?;
println!("Decrypted message: {}", decrypted_msg);
// 6. Password-based encryption
println!("\n--- 6. Password-Based Encryption ---");
let password = "my_secure_password";
let secret = "This is a secret message";
let (encrypted_pwd, salt, nonce_pwd) = encrypt_with_password(password, secret)?;
println!("Password-encrypted: {}", encrypted_pwd);
println!("Salt: {}", hex::encode(salt));
println!("Nonce: {}", hex::encode(nonce_pwd));
let decrypted_pwd = decrypt_with_password(password, &encrypted_pwd, salt, nonce_pwd)?;
println!("Decrypted: {}", decrypted_pwd);
// 7. Key from password
println!("\n--- 7. Key Derivation ---");
let user_password = "user_password_123";
let user_salt = [0u8; 32]; // In practice, generate random salt
let derived_key = key_from_password(user_password, &user_salt, 100_000);
println!("Derived key: {}", hex::encode(derived_key));
// 8. Encrypt large data
println!("\n--- 8. Large Data Encryption ---");
let large_data = "A".repeat(10000);
let large_encrypted = encrypt_string_aes256_gcm(&key, &nonce, &large_data)?;
println!("Encrypted {} bytes to {}", large_data.len(), large_encrypted.len());
// 9. Chunked encryption
println!("\n--- 9. Chunked Encryption ---");
let test_data = b"This is some test data that will be encrypted in chunks";
let chunks = encrypt_chunked(&key, test_data, 10)?;
println!("Encrypted into {} chunks", chunks.len());
// 10. Verify data integrity
println!("\n--- 10. Data Integrity ---");
let original = "Important data to protect";
let enc = encrypt_message(&key, original)?;
let dec = decrypt_message(&key, enc)?;
println!("Original matches decrypted: {}", original == dec);
println!("\n=== All Symmetric Encryption Examples Completed ===");
Ok(())
}