使用 HMAC 作为泛型
Using HMAC as a generic
我在更新 crate hmac
和 digest
时遇到问题。我定义了一个函数,它采用通用类型的 HMAC 函数,并计算给定输入的 HMAC。我有一个函数使用 hmac
和 digest
的版本分别为 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]);
}
我在更新 crate hmac
和 digest
时遇到问题。我定义了一个函数,它采用通用类型的 HMAC 函数,并计算给定输入的 HMAC。我有一个函数使用 hmac
和 digest
的版本分别为 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]);
}