feat: crypto/ring

This commit is contained in:
2021-01-10 23:02:37 +08:00
parent e73575f62e
commit 9c33fca074

View File

@@ -1,8 +1,8 @@
use ring::{ use std::num::NonZeroU32;
signature::{ KeyPair, Ed25519KeyPair, UnparsedPublicKey, ED25519 },
hmac, rand, error::Unspecified, use aead::{NONCE_LEN, Nonce, UnboundKey};
digest, 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; 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()); let verify_result = UnparsedPublicKey::new(&ED25519, &public_key).verify(&"hello world".as_bytes(), sig.as_ref());
println!("verify: {}", verify_result.is_ok()); 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(()) Ok(())
} }
pub trait Crypto: Send + Sync {
fn encrypt(&self, buf: &mut Vec<u8>);
fn decrypt(&self, buf: &mut Vec<u8>) -> 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<u8>) {
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<u8>) -> 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
}
}