novax_rsa_async/
lib.rs

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}