首页 > 解决方案 > 使用 HMAC 作为泛型

问题描述

我在更新 cratehmacdigest. 我定义了一个函数,它采用 HMAC 函数的泛型类型,并通过给定的输入计算 HMAC。我有一个函数分别使用 0.7 和 0.8hmac的版本。digest但是,在尝试分别为最新版本 0.10 和 0.9 运行相同的逻辑时,我被阻止了。

在我的机器中,我使用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 函数?

对不起,很长的帖子,我希望我能把我的问题说清楚。感谢社区!

标签: rusthmac

解决方案


最好查看跨版本更新更新的示例代码,幸运的是在其存储库中hmac一些测试。

这些测试使用在crate中定义new_test宏。特别是,有一条与您相似的线...crypto-mac

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

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

在实现您已经确定的命名法更新后,您的代码as NewMac将使用上面的附加转换,以及+ NewMac绑定在的相应新特征D

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]);
}

推荐阅读