rust - 为什么在实现 HMAC-SHA256 时得到不正确的值?

标签 rust sha256 hmac

我正在尝试在 Rust 中创建一个函数,它将返回 HMAC-SHA256 摘要。我一直在根据Wikipedia的描述进行工作和 RFC 2104 .

我一直在努力返回正确的 HMAC。我正在使用ring对于 SHA256 摘要,但无论我尝试什么,我似乎都无法得到正确的结果。我怀疑这可能与 .as_ref().to_vec() 转换有关。即使这是真的,我也不知道如何继续下去。以下代码并未实现 RFC 2104 中的所有内容,但它突出了我的问题。

extern crate ring;
use ring::{digest, test};

pub fn hmac(k: Vec<u8>, mut m: Vec<u8>) -> Vec<u8> {
    // Initialize ipad and opad as byte vectors with SHA256 blocksize
    let ipad = vec![0x5C; 64];
    let opad = vec![0x36; 64];
    // iround and oround are used to seperate the two steps with XORing
    let mut iround = vec![];
    let mut oround = vec![];

    for count in 0..k.len() {
        iround.push(k[count] ^ ipad[count]);
        oround.push(k[count] ^ opad[count]);
    }

    iround.append(&mut m); // m is emptied here
    iround = (digest::digest(&digest::SHA256, &iround).as_ref()).to_vec();
    oround.append(&mut iround); // iround is emptied here
    oround = (digest::digest(&digest::SHA256, &oround).as_ref()).to_vec();
    let hashed_mac = oround.to_vec();

    return hashed_mac;
}

#[test]
fn test_hmac_digest() {
    let k = vec![0x61; 64];
    let m = vec![0x62; 64];
    let actual = hmac(k, m);
    // Expected value taken from: https://www.freeformatter.com/hmac-generator.html#ad-output
    let expected = test::from_hex("f6cbb37b326d36f2f27d294ac3bb46a6aac29c1c9936b985576041bfb338ae70").unwrap();
    assert_eq!(actual, expected);
}

这些是摘要:

Actual = [139, 141, 144, 52, 11, 3, 48, 112, 117, 7, 56, 151, 163, 65, 152, 195, 163, 164, 26, 250, 178, 100, 187, 230, 89, 61, 191, 164, 146, 228, 180, 62]

Expected = [246, 203, 179, 123, 50, 109, 54, 242, 242, 125, 41, 74, 195, 187, 70, 166, 170, 194, 156, 28, 153, 54, 185, 133, 87, 96, 65, 191, 179, 56, 174, 112]

最佳答案

正如评论中提到的,您已经交换了内部和外部填充的字节。请参阅Wikipedia page :

o_key_pad = key xor [0x5c * blockSize]   //Outer padded key
i_key_pad = key xor [0x36 * blockSize]   //Inner padded key

这是我对该函数的看法。我相信它的分配较少:

extern crate ring;

use ring::{digest, test};

const BLOCK_SIZE: usize = 64;

pub fn hmac(k: &[u8], m: &[u8]) -> Vec<u8> {
    assert_eq!(k.len(), BLOCK_SIZE);

    let mut i_key_pad: Vec<_> = k.iter().map(|&k| k ^ 0x36).collect();
    let mut o_key_pad: Vec<_> = k.iter().map(|&k| k ^ 0x5C).collect();

    i_key_pad.extend_from_slice(m);

    let hash = |v| digest::digest(&digest::SHA256, v);

    let a = hash(&i_key_pad);

    o_key_pad.extend_from_slice(a.as_ref());

    hash(&o_key_pad).as_ref().to_vec()
}

#[test]
fn test_hmac_digest() {
    let k = [0x61; BLOCK_SIZE];
    let m = [0x62; BLOCK_SIZE];
    let actual = hmac(&k, &m);

    // Expected value taken from: https://www.freeformatter.com/hmac-generator.html#ad-output
    let expected = test::from_hex("f6cbb37b326d36f2f27d294ac3bb46a6aac29c1c9936b985576041bfb338ae70").unwrap();
    assert_eq!(actual, expected);
}

关于rust - 为什么在实现 HMAC-SHA256 时得到不正确的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48630814/

相关文章:

enums - 在枚举方法中改变 self

singleton - 如何让 Rust 单例的析构函数运行?

erlang - Erlang中字符串的HMAC SHA256十六进制摘要,如何?

swift - Vapor 加密 : expression type 'Data' is ambiguous without more context

java - GlassFish SHA-256 摘要认证

c# - 为什么 ComputeHash 的行为不是确定性的?

rust - 错误[E0502] : cannot borrow `vector` as immutable because it is also borrowed as mutable

macros - 在 Rust 的过程宏中使用 $crate?

javascript - HMAC/Javascript - 在哪里存储 secret ?

java - Java 和 PHP 之间的 Base64_encode 不同