use crabgraph::{
aead::{AesGcm256, CrabAead},
encoding::base64_encode,
kdf::pbkdf2_derive_sha256,
CrabResult,
};
fn main() -> CrabResult<()> {
println!("=== CryptoJS Interoperability Example ===\n");
println!("This example shows how to work with data encrypted by CryptoJS.");
println!("Note: CryptoJS typically uses AES-CBC with PKCS7 padding,");
println!("while we recommend AES-GCM for better security.\n");
password_based_encryption_example()?;
key_derivation_example()?;
Ok(())
}
fn password_based_encryption_example() -> CrabResult<()> {
println!("1. Password-Based Encryption:");
let password = b"my_secret_password";
let plaintext = b"Hello, CryptoJS!";
let salt = crabgraph::rand::secure_bytes(16)?;
println!(" Password: {}", String::from_utf8_lossy(password));
println!(" Salt: {}", base64_encode(&salt));
let iterations = 100_000; let key = pbkdf2_derive_sha256(password, &salt, iterations, 32)?;
println!(" Iterations: {} (CryptoJS default: 1 - INSECURE!)", iterations);
println!(" Key derived: {} bytes", key.len());
let cipher = AesGcm256::new(key.as_slice())?;
let ciphertext = cipher.encrypt(plaintext, None)?;
let serialized = ciphertext.to_base64();
println!(" Ciphertext (base64): {}...", &serialized[..40]);
let recovered = crabgraph::aead::Ciphertext::from_base64(&serialized, 12, 16)?;
let decrypted = cipher.decrypt(&recovered, None)?;
assert_eq!(decrypted, plaintext);
println!(" Decrypted: {}", String::from_utf8_lossy(&decrypted));
println!(" ✓ Password-based encryption successful!\n");
Ok(())
}
fn key_derivation_example() -> CrabResult<()> {
println!("2. Key Derivation (CryptoJS-compatible approach):");
println!(" ⚠️ CryptoJS uses MD5 for default key derivation (INSECURE!)");
println!(" ✓ We use PBKDF2-HMAC-SHA256 for better security");
let password = b"password123";
let salt = b"saltdata12345678";
let key = pbkdf2_derive_sha256(password, salt, 100_000, 32)?;
println!(" Derived key length: {} bytes", key.len());
println!(" ✓ Secure key derivation complete!\n");
println!("🔧 Migration Advice:");
println!(" - Use AES-GCM instead of AES-CBC for authenticated encryption");
println!(" - Use PBKDF2 with ≥100,000 iterations (or Argon2)");
println!(" - Generate random salts (≥16 bytes)");
println!(" - Never reuse nonces with the same key");
println!(" - See docs/MIGRATE_CRYPTOJS.md for detailed guide");
Ok(())
}