1use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
2use std::error::Error;
3use novax_tokio::tokio as tokio;
4use tokio::sync::oneshot;
5use std::thread;
6
7pub async fn key_pair() -> Result<(RsaPrivateKey, RsaPublicKey ), Box<dyn Error>> {
8 let (tx, rx) = oneshot::channel::<(Option<RsaPrivateKey>, Option<RsaPublicKey> )>();
9 std::thread::spawn(move || {
10 let mut rng = rand::thread_rng();
11 let bits = 2048;
12 let _ = tx.send(
13 match RsaPrivateKey::new(&mut rng, bits) {
14 Ok(priv_key) => {
15 let pub_key = RsaPublicKey::from(&priv_key);
16 ( Some(priv_key), Some(pub_key))
17 },
18 Err(e) => {
19 eprintln!("error create private key {:?}", e);
20 ( None, None)
21 }
22 }
23 );
24 });
25 let keys = rx.await?;
26 if let( Some(priv_key), Some(pub_key) ) = keys {
27 return Ok((priv_key, pub_key))
28 }
29 Err(rsa::Error::InputNotHashed.into())
30}
31
32pub async fn encrypt(buf: Vec<u8>, pub_key: RsaPublicKey) -> Result<Vec<u8>, Box<dyn Error>> {
33 let (tx, rx) = oneshot::channel::<Result<Vec<u8>, rsa::Error>>();
34 thread::spawn(move || {
35 let mut rng = rand::thread_rng();
36 let rslt = pub_key.encrypt(&mut rng, Pkcs1v15Encrypt, &buf[..]);
37 let _ = tx.send(rslt);
38 });
39 let rslt = rx.await?;
40 Ok(rslt?)
41}
42
43pub async fn decrypt(enc_data: Vec<u8>, priv_key: RsaPrivateKey) -> Result<Vec::<u8>, Box<dyn Error>> {
44 let (tx, rx) = oneshot::channel::<Result<Vec<u8>, rsa::Error>>();
45 thread::spawn(move || {
46 let dec_data = priv_key.decrypt(Pkcs1v15Encrypt, &enc_data);
47 let _ = tx.send(dec_data);
48 });
49 let rslt = rx.await?;
50 Ok(rslt?)
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[tokio::test]
58 async fn should_encrypt_decrypt_async_the_same() -> Result<(), Box<dyn Error>> {
59 let (p0, p1) = key_pair().await?;
60 let data_str = b"hello testing async!!!";
61 let enc_data = encrypt(data_str.to_vec(), p1).await?;
62 let dec_data = decrypt(enc_data, p0).await?;
63 assert_eq!(dec_data, data_str, "decrypt data string same as input string" );
64 Ok(())
65 }
66}