risingwave_expr_impl/scalar/
hmac.rs1use hmac::{Hmac, Mac};
16use risingwave_expr::{ExprError, Result, function};
17use sha1::Sha1;
18use sha2::Sha256;
19
20#[function("hmac(varchar, bytea, varchar) -> bytea")]
21pub fn hmac(secret: &str, payload: &[u8], sha_type: &str) -> Result<Box<[u8]>> {
22 if sha_type == "sha1" {
23 Ok(hmac_sha1(secret, payload))
24 } else if sha_type == "sha256" {
25 Ok(hmac_sha256(secret, payload))
26 } else {
27 return Err(ExprError::InvalidParam {
28 name: "sha_type",
29 reason: format!("Unsupported SHA type: {}", sha_type).into(),
30 });
31 }
32}
33
34fn hmac_sha256(secret: &str, payload: &[u8]) -> Box<[u8]> {
35 let mut mac =
36 Hmac::<Sha256>::new_from_slice(secret.as_bytes()).expect("HMAC can take key of any size");
37 mac.update(payload);
38
39 let code_bytes = mac.finalize().into_bytes();
40 code_bytes.as_slice().into()
41}
42
43fn hmac_sha1(secret: &str, payload: &[u8]) -> Box<[u8]> {
44 let mut mac =
45 Hmac::<Sha1>::new_from_slice(secret.as_bytes()).expect("HMAC can take key of any size");
46 mac.update(payload);
47
48 let code_bytes = mac.finalize().into_bytes();
49 code_bytes.as_slice().into()
50}
51
52#[cfg(test)]
53mod tests {
54 use hex::encode;
55
56 use super::*;
57
58 #[test]
59 fn test_verify_signature_hmac_sha256() {
60 let secret = "your_secret_key";
61 let payload = b"your_webhook_payload";
62 let signature = "cef8b98a91902c492b85d97f049aa4bfc5e7e3f9b8b7bf7cb49c5f829d2dac85";
63 assert!(encode(hmac_sha256(secret, payload)) == signature);
64 }
65
66 #[test]
67 fn test_verify_signature_hmac_sha1() {
68 let secret = "your_secret_key";
69 let payload = b"your_webhook_payload";
70 let signature = "65cb920a4b8c6ab8e2eab861a096a7bc2c05d8ba";
71 assert!(encode(hmac_sha1(secret, payload)) == signature);
72 }
73}