使用 HMAC 作为泛型

Using HMAC as a generic

我在更新 crate hmacdigest 时遇到问题。我定义了一个函数,它采用通用类型的 HMAC 函数,并计算给定输入的 HMAC。我有一个函数使用 hmacdigest 的版本分别为 0.7 和 0.8。但是,当我试图分别为最新版本 0.10 和 0.9 获取相同的逻辑时,我被阻止了。运行ning。

在我的机器上,我使用 rustc 1.48.0 (7eac88abb 2020-11-16)

工作示例具有以下 Cargo.toml 依赖项

[dependencies]
hmac = "0.7"
sha2 = "0.8"
digest = "0.8"

最小的工作示例如下:

use sha2::{Sha256};
use hmac::{Mac, Hmac};

type HmacSha256 = Hmac<Sha256>;
use digest::generic_array::typenum::{U32};

pub struct Key([u8; 2]);

impl Key {
    pub fn print_hmac<D>(&self, message: &[u8])
    where
        D: Mac<OutputSize = U32>,
    {
        let mut mac = D::new_varkey(self.0.as_ref()).unwrap();
        mac.input(message);

        let result = mac.result();
        let code_bytes = result.code();
        println!("{:?}", code_bytes)
    }
}

pub fn main() {
    let verif_key = Key([12u8, 33u8]);
    verif_key.print_hmac::<HmacSha256>(&[83u8, 123u8]);
}

以上代码运行良好,可以编译。但是,当我尝试将依赖项升级到最新版本时,一切都崩溃了。

已更新Cargo.toml

[dependencies]
hmac = "0.10"
sha2 = "0.9"
digest = "0.9"

随着更新,我们对命名法进行了一些更改:

.input() -> .update()
.result() -> .finalize()
.code() -> .into_bytes()

当我尝试 运行 它时,出现以下错误

no function or associated item named 'new_varkey' found for type parameter 'D' in the current scope

所以我尝试将通用类型定义为NewMac(为此需要将第二行更改为use hmac::{Mac, Hmac, NewMac};)。但是,现在错误出现在函数 .update().finalize().

我还尝试传递 Digest 泛型,而不是 Hmac,如下所示:

pub fn print_hmac<D>(&self, message: &[u8])
    where
        D: Digest,
    {
        let mut mac = Hmac::<D>::new_varkey(self.0.as_ref()).unwrap();
        mac.update(message);

        let result = mac.finalise();
        let code_bytes = result.into_bytes();
        println!("{:?}", code_bytes)
    }

但还是不行。

我应该如何处理更新后的 crate 的通用 Hmac 函数?

抱歉这么久了 post,我希望我把问题说清楚了。感谢社区!

最好查看跨版本更新的示例代码,幸运的是 hmac 在其存储库中有 some tests

这些测试使用 crypto-mac 包中 here 定义的 new_test 宏。特别是,有一行与你的相似...

let mut mac = <$mac as NewMac>::new_varkey(key).unwrap();

...这表明 D 也应该在您的代码中转换为 NewMac 实现者。

在实施您已经确定的命名法更新后,您的代码可以使用上面的额外 as NewMac 强制转换,以及 D 上相应的新 + NewMac 特征绑定:

use sha2::{Sha256};
use hmac::{NewMac, Mac, Hmac};

type HmacSha256 = Hmac<Sha256>;
use digest::generic_array::typenum::{U32};

pub struct Key([u8; 2]);

impl Key {
    pub fn print_hmac<D>(&self, message: &[u8])
    where
        D: Mac<OutputSize = U32> + NewMac,       // `+ NewMac` input trait bound
    {
        let mut mac = <D as NewMac>::new_varkey(self.0.as_ref()).unwrap();     // `as NewMac` cast
        mac.update(message);

        let result = mac.finalize();
        let code_bytes = result.into_bytes();
        println!("{:?}", code_bytes)
    }
}

pub fn main() {
    let verif_key = Key([12u8, 33u8]);
    verif_key.print_hmac::<HmacSha256>(&[83u8, 123u8]);
}