为什么我没有从秘密中得到正确的顶部

问题描述 投票:0回答:1
use hmac::{Hmac, Mac};
use sha1::Sha1;

type hmacsha1 = Hmac<Sha1>;

fn main() {
    let key = "JBSWY3DPEHPK3PXP";
    let step: u32 = 30;
    let skew: u32 = 1;
    let mut hmac = hmacsha1::new_from_slice(key.as_bytes()).unwrap();
    let time = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let time = time as u32 / step;

    hmac.update(&time.to_be_bytes());

    let mut result = hmac.finalize().into_bytes().to_vec();
    let offset = result.last().unwrap() & 15;
    let binary = (result[offset as usize] as u32 & 0x7f) << 24
        | (result[(offset + 1) as usize] as u32 & 0xff) << 16
        | (result[(offset + 2) as usize] as u32 & 0xff) << 8
        | (result[(offset + 3) as usize] as u32 & 0xff);
    let mut fin = binary % 10_u32.pow(6);
    let fin_str = fin.to_string();

    println!("{:?}", result.last());
    println!("{:?}", fin_str);
}

当我为秘密运行此代码时,我没有得到预期的输出,我遵循了 totp 参考表并致力于他们在 java 中给出的实现,但它不起作用,有人可以看到我没有看到的东西吗

我期待正确的结果

rust hash cryptography totp
1个回答
0
投票

通常,HOTP 或 TOTP 的密钥以 Base32 字符串形式给出,有时以十六进制或 Base64 字符串形式给出,尽管这些不太常见。但是,您实际上使用字符串作为密钥,而不是对其进行解码。

您可能想使用 base32 crate 将其解码为字节值。

此外,我可能建议您编写的代码在密钥和时间戳上更加通用,这将允许您在这里编写一些测试。很明显,它不会产生“正确的结果”,但如果您可以为已知值编写一些测试,那么就更容易知道您的代码是否确实做到了这一点。尤其如此,因为它涉及时间,而时间是一个移动的目标。

© www.soinside.com 2019 - 2024. All rights reserved.