use std::num::NonZeroU32; use aead::{NONCE_LEN, Nonce, UnboundKey}; use rand::SystemRandom; use ring::{aead::{self, LessSafeKey}, digest, error::Unspecified, hmac, pbkdf2, rand::SecureRandom, rand, signature::{ KeyPair, Ed25519KeyPair, UnparsedPublicKey, ED25519 }}; const SEED_LEN: usize = 32; fn main() -> Result<(), Unspecified> { { println!("{} HHmac {}", "-".repeat(10), "-".repeat(10)); let rng = rand::SystemRandom::new(); let key = hmac::Key::generate(hmac::HMAC_SHA256, &rng)?; let msg = "hello, world"; let tag = hmac::sign(&key, msg.as_bytes()); println!("{:?}", tag); hmac::verify(&key, msg.as_bytes(), tag.as_ref())?; println!("Verify success"); } { println!("{} SHA256 {}", "-".repeat(10), "-".repeat(10)); let sha256 = digest::digest(&digest::SHA256, b"hello, world"); println!("{:?}", sha256); } { println!("{} EdDSA {}", "-".repeat(10), "-".repeat(10)); let rng = rand::SystemRandom::new(); let seed: [u8; SEED_LEN] = rand::generate(&rng)?.expose(); println!("seed: {}", hex::encode(&seed)); let key_pair = Ed25519KeyPair::from_seed_unchecked(&seed)?; println!("private: {:?}", key_pair); let sig = key_pair.sign(&"hello world".as_bytes()); println!("signature: {}", hex::encode(sig.as_ref())); let public_key = key_pair.public_key().as_ref(); let verify_result = UnparsedPublicKey::new(&ED25519, &public_key).verify(&"hello world".as_bytes(), sig.as_ref()); println!("verify: {}", verify_result.is_ok()); } { println!("{} Random {}", "-".repeat(10), "-".repeat(10)); let mut random_bytes = [0_u8; 32]; let random = SystemRandom::new(); random.fill(&mut random_bytes).unwrap(); println!("Random bytes: {}", hex::encode(&random_bytes)); } { println!("{} Aead Crypto {}", "-".repeat(10), "-".repeat(10)); let mut key = vec![]; for _ in 0..16 { key.push(0_u8); } let aead_crypto = AeadCrypto::new(&key, &aead::AES_128_GCM); let mut text = "hello world".as_bytes().to_vec(); println!("Cleartext: {}", hex::encode(&text)); aead_crypto.encrypt(&mut text); println!("Encrypted: {}", hex::encode(&text)); let decrypt_result = aead_crypto.decrypt(&mut text); println!("Decrypted: {}, text: {}", decrypt_result, hex::encode(text)); } Ok(()) } pub trait Crypto: Send + Sync { fn encrypt(&self, buf: &mut Vec); fn decrypt(&self, buf: &mut Vec) -> bool; } pub struct AeadCrypto { key: LessSafeKey, algorithm: &'static aead::Algorithm, random: SystemRandom, } impl AeadCrypto { pub fn new(key: &[u8], algorithm: &'static aead::Algorithm) -> Self { let salt = b"ap-kcp-aead-salt"; let mut key_bytes = Vec::with_capacity(algorithm.key_len()); key_bytes.resize(algorithm.key_len(), 0); pbkdf2::derive( pbkdf2::PBKDF2_HMAC_SHA256, NonZeroU32::new(32).unwrap(), salt, key, &mut key_bytes, ); let key = UnboundKey::new(algorithm, &key_bytes).unwrap(); let key = LessSafeKey::new(key); Self { key, algorithm, random: SystemRandom::new(), } } } impl Crypto for AeadCrypto { fn encrypt(&self, buf: &mut Vec) { let mut nonce_bytes = [0u8; NONCE_LEN]; self.random.fill(&mut nonce_bytes).unwrap(); let nonce = Nonce::assume_unique_for_key(nonce_bytes); // | ENCRPYTED | TAG | NONCE | self.key .seal_in_place_append_tag(nonce, aead::Aad::empty(), buf) .unwrap(); buf.extend_from_slice(&nonce_bytes); } fn decrypt(&self, buf: &mut Vec) -> bool { if buf.len() < aead::NONCE_LEN + self.algorithm.tag_len() { return false; } let len = buf.len(); let mut nonce_bytes = [0u8; aead::NONCE_LEN]; nonce_bytes.copy_from_slice(&buf[len - aead::NONCE_LEN..]); let nonce = Nonce::assume_unique_for_key(nonce_bytes); buf.truncate(len - aead::NONCE_LEN); let len = if let Ok(plaintext) = self.key.open_in_place(nonce, aead::Aad::empty(), buf) { plaintext.len() } else { println!("[ERROR] failed to decrypt"); return false; }; buf.truncate(len); true } }