ultimate_common/
digest.rs

1use base64ct::{Base64UrlUnpadded, Encoding};
2pub use hmac::digest::InvalidLength;
3use hmac::{
4  digest::{
5    generic_array::GenericArray,
6    typenum::{UInt, UTerm, B0, B1},
7    CtOutput,
8  },
9  Hmac, Mac,
10};
11use sha2::{Digest, Sha256};
12
13use crate::Error;
14
15type HmacSha256 = Hmac<Sha256>;
16
17pub fn hmac_sha256(secret: &[u8], s: &[u8]) -> Result<CtOutput<HmacSha256>, InvalidLength> {
18  let mut mac = HmacSha256::new_from_slice(secret)?;
19  mac.update(s);
20  let result = mac.finalize();
21  Ok(result)
22}
23
24#[inline]
25pub fn hmac_sha256_string(secret: &[u8], s: &[u8]) -> Result<String, InvalidLength> {
26  let bytes = hmac_sha256(secret, s)?.into_bytes();
27  Ok(base16ct::lower::encode_string(&bytes))
28}
29
30type ShaArray = GenericArray<u8, UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>, B0>>;
31
32pub fn sha256(s: &[u8]) -> ShaArray {
33  let mut hasher: Sha256 = Sha256::new();
34  hasher.update(s);
35  hasher.finalize()
36}
37
38#[inline]
39pub fn sha256_string(s: &[u8]) -> String {
40  let result = sha256(s);
41  base16ct::lower::encode_string(&result)
42}
43
44pub fn b64u_encode(content: impl AsRef<[u8]>) -> String {
45  Base64UrlUnpadded::encode_string(content.as_ref())
46}
47
48pub fn b64u_decode(b64u: &str) -> Result<Vec<u8>, Error> {
49  Base64UrlUnpadded::decode_vec(b64u).map_err(|_| Error::FailToB64uDecode(b64u.to_string()))
50}
51
52pub fn b64u_decode_to_string(b64u: &str) -> Result<String, Error> {
53  b64u_decode(b64u).ok().and_then(|r| String::from_utf8(r).ok()).ok_or(Error::FailToB64uDecode(b64u.to_string()))
54}