rok-core 0.6.1

Core primitives for the rok ecosystem — errors, crypto, i18n, config, DI, and more
Documentation
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use hmac::{Hmac, Mac};
use sha2::Sha256;

use crate::crypto::encrypt::config::EncryptConfig;

type HmacSha256 = Hmac<Sha256>;

#[derive(Clone)]
pub struct Signer {
    key: Vec<u8>,
}

impl Signer {
    pub fn new(key: impl AsRef<str>) -> Self {
        Self {
            key: key.as_ref().as_bytes().to_vec(),
        }
    }

    pub fn from_config(config: &EncryptConfig) -> Self {
        Self::new(&config.key)
    }

    pub fn sign(&self, data: &str) -> String {
        let mut mac =
            HmacSha256::new_from_slice(&self.key).expect("HMAC accepts keys of any length");
        mac.update(data.as_bytes());
        URL_SAFE_NO_PAD.encode(mac.finalize().into_bytes())
    }

    pub fn verify(&self, data: &str, signature: &str) -> bool {
        let Ok(sig_bytes) = URL_SAFE_NO_PAD.decode(signature) else {
            return false;
        };
        let mut mac =
            HmacSha256::new_from_slice(&self.key).expect("HMAC accepts keys of any length");
        mac.update(data.as_bytes());
        mac.verify_slice(&sig_bytes).is_ok()
    }
}