简体   繁体   English

Output 的密码散列 function 不会产生与 Z23EEEB4347BDD256BFCZB36 中相同的 output

[英]Output of cryptographic hashing function does not produce the same output as in python

I'm trying to get a message authentication system going on the Arduino.我正在尝试在 Arduino 上运行消息身份验证系统。 I've found the Arduino Cryptographic Library which seems to do what I want, except I can't get it to agree with the python hash.我找到了Arduino 加密库,它似乎可以满足我的要求,但我无法让它与 python hash 一致。

I have chosen to use the Blake2s protocol.我选择使用 Blake2s 协议。 In Python it seems to be pretty straightforward:在 Python 中,它似乎很简单:

import hashlib

message = b'This is a test'
key = b'secret'

h = hashlib.blake2s(digest_size=32, key=key)
h.update(message)
print(h.hexdigest().encode('utf-8'))

Prints b'06082b17a536da2054dd3f1f75baafd84ac8d65eba56dd6f882d723292393ffd' .打印b'06082b17a536da2054dd3f1f75baafd84ac8d65eba56dd6f882d723292393ffd'

Unfortunately the documentation of the library is spotty at best, and I have to admit I'm not following 100%.不幸的是,图书馆的文档充其量是参差不齐的,我不得不承认我没有 100% 关注。 It isn't helping that I rarely program in C (I'm usually a Fortran/Python programmer).我很少用 C 编程(我通常是 Fortran/Python 程序员),这于事无补。 The only 'example' I could find on how to use this library is a unit test, with lots of magic numbers .我能找到的关于如何使用这个库的唯一“例子”是一个单元测试,有很多幻数 But I think the meat of the HMAC process is in lines 202-207 of that file:但我认为 HMAC 过程的核心在该文件的第 202-207 行:

// Now use the library to compute the HMAC.
hash->resetHMAC(buffer, keyLen);
memset(buffer, 0xBA, sizeof(buffer));
hash->update(buffer, sizeof(buffer));
memset(buffer, (uint8_t)keyLen, keyLen);
hash->finalizeHMAC(buffer, keyLen, buffer, HASH_SIZE);

So here's what I came up with:所以这就是我想出的:

#include <Crypto.h>
#include <BLAKE2s.h>
#include <stdlib.h>

#define HASH_SIZE 32

#define MESSAGE "This is a test"
#define KEY "secret"
#define SIGNATURE "06082b17a536da2054dd3f1f75baafd84ac8d65eba56dd6f882d723292393ffd"

void hexstring_to_array(String value_string, uint8_t value[HASH_SIZE]){
    char buf[3];
    for (uint8_t i=0; i<HASH_SIZE; i++){
        value_string.substring(2*i, 2*i+2).toCharArray(buf, 3);
        buf[2] = '\n';
        value[i] = strtoll(buf, NULL, 16);
    }
}

void calculate_signature(Hash *hash, char * message, size_t message_len, char * key, size_t key_len, uint8_t sig[HASH_SIZE]){
    hash -> resetHMAC(key, key_len);
    hash -> update(message, message_len);
    hash -> finalizeHMAC(key, key_len, sig, HASH_SIZE);
}

void setup(){
    BLAKE2s blake2s;
    Serial.begin(115200);
    char message[] = (MESSAGE);
    char key[] = (KEY);
    uint8_t good_sig[HASH_SIZE];
    uint8_t sig[HASH_SIZE];
    hexstring_to_array(SIGNATURE, sig);
    calculate_signature(&blake2s, message, sizeof(message), key, sizeof(key), good_sig);
    if (memcmp(sig, good_sig, HASH_SIZE) == 0) {
        Serial.println("Yes");
    } else {
        Serial.println("No");
    }
}

I've checked the output, it's b7d9f4091c44596d5545edc79a17f6448e04d3be39d909d62e0d3dfed2fb1d94 , so clearly not the same.我检查了 output,它是b7d9f4091c44596d5545edc79a17f6448e04d3be39d909d62e0d3dfed2fb1d94 ,所以显然不一样。 I've played around with the trailing \0 character (leaving it out by reducing the length arguments, or adding it to the python script), but that didn't help.我玩过尾随的\0字符(通过减少长度 arguments 或将其添加到 python 脚本中将其排除在外),但这没有帮助。

If someone just had some pointers to more understandable resources, that would help me.如果有人只是有一些指向更易于理解的资源的指针,那将对我有所帮助。

(This is a hobby. I understand that the code is crude and probably full of ugly code smell and potentially some bugs. I'm working on this in my limited spare time.) (这是一种爱好。我知道代码很粗糙,可能充满了难看的代码气味,并且可能存在一些错误。我在有限的业余时间从事这个工作。)

Thank you谢谢

Thank you @dandavis, you pointed out what I was missing.谢谢@dandavis,您指出了我所缺少的。 My main issue was the Python part, not the Arduino code.我的主要问题是 Python 部分,而不是 Arduino 代码。 Here is the correct python implementation:这是正确的 python 实现:

import hmac

key = "secret"
message = "This is a test"

h = hmac.new(key=key.encode(), digestmod='blake2s')
h.update(message.encode())
print(h.hexdigest())

This prints a64f8cd3aee4b1d6a7a89eec6b60da153ba0a484656d6ffeb8a7061fe695f4ff这将打印a64f8cd3aee4b1d6a7a89eec6b60da153ba0a484656d6ffeb8a7061fe695f4ff

There was also a minor bug in the Arduino code, as @Majenko pointed out, I needed to replace the sizeof with strlen methods in the call to calculate_signature . Arduino 代码中还有一个小错误,正如@Majenko 指出的那样,我需要在调用calculate_signature时用strlen方法替换sizeof (And yes, I also replaced the '\n' with '\0' .) (是的,我也用'\0'替换了'\n' ' 。)

With these changes, the Arduino code produces the same digest.通过这些更改,Arduino 代码生成相同的摘要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM