From 9c33fca07428c47b4560607be53fb324e63ccad2 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 10 Jan 2021 23:02:37 +0800 Subject: [PATCH] feat: crypto/ring --- __crypto/ring/src/main.rs | 99 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 5 deletions(-) diff --git a/__crypto/ring/src/main.rs b/__crypto/ring/src/main.rs index f48f0bb..1aeeb01 100644 --- a/__crypto/ring/src/main.rs +++ b/__crypto/ring/src/main.rs @@ -1,8 +1,8 @@ -use ring::{ - signature::{ KeyPair, Ed25519KeyPair, UnparsedPublicKey, ED25519 }, - hmac, rand, error::Unspecified, - digest, -}; +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; @@ -37,6 +37,95 @@ fn main() -> Result<(), Unspecified> { 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 + } +}