Вычислить SHA256 строки и вывести в строку

В моем проекте Arduino я хочу вычислить хэш SHA256 строки и сохранить результат в строку, и сделать это рекурсивно много раз (т. е. вычислить хэш хэша хэша и т. д.). Итак, моя цель — иметь надежную функцию следующим образом:

String h(String input) {
...
return output;
}

где, например, h("abc") вернет "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad".

Я скачал эту библиотеку. (из Инструменты->Управление библиотеками, он также находится в github), а затем запустил пример в TestSHA256.ino, который проходит все проверки. Однако я изо всех сил пытаюсь заставить свою функцию работать, поскольку в библиотеке нет конкретного примера того, как вычислить и вернуть хэш SHA256.

Я искал функцию testHash_N() в TestSHA256.ino, которая создает хэш (из данных struct TestHashVector) и сравнивает его с предварительно вычисленным хешем (из хэша struct TestHashVector[]).

Похоже, хэш вычисляется в строках 89–96 в TestSHA256.ino. Я просто хочу получить фактический результат хэш-строки, поэтому для testVectorSHA256_1 в примере мне нужно было бы получить строку = "ba7816bf....15ad" в качестве результата.

Я понимаю, что это связано с обращением к памяти в Arduino, но у меня нет опыта, поэтому я был бы признателен, если бы вы помогли мне с этим.

EDIT: мой фрагмент кода выглядит следующим образом, но он не выводит правильный хеш..

#include <Crypto.h>
#include <SHA256.h>
#include <string.h>

#define HASH_SIZE 32
#define BLOCK_SIZE 64

char hex[256];

char *hashvalue;

SHA256 sha256;

byte buffer[128];


char *btoh(char *dest, uint8_t *src, int len) {
  char *d = dest;
  while( len-- ) sprintf(d, "%02x", (unsigned char)*src++), d += 2;
  return dest;
}

char* h(Hash *hash, char* hashvalue)
{
    size_t size = sizeof(&hashvalue);
    size_t posn, len;
    size_t inc = sizeof(&hashvalue);
    uint8_t value[HASH_SIZE];

    hash->reset();
    for (posn = 0; posn < size; posn += inc) {
        len = size - posn;
        if (len > inc)
            len = inc;
        hash->update(&hashvalue + posn, len);
    }
    hash->finalize(value, sizeof(value));

    return(btoh(hex, value, 32));
}


void setup()
{
    Serial.begin(115200);

    bool tmp;
    char *testvalue = "abc";
    Serial.println(h(&sha256,*testvalue));


}

void loop()
{
}

, 👍2

Обсуждение

Подсказка №1: sizeof(&hashvalue); не является длиной строки. Это количество байтов указателя., @Mikael Patel

Подсказка №2: *testvalue в операторе h(&sha256,*testvalue)); не является указателем. На самом деле это значение первого символа a в testvalue., @Mikael Patel

Подсказка №3: uint8_t value[HASH_SIZE]; является локальным значением и не может быть возвращено. static uint8_t value[HASH_SIZE]; позволит это., @Mikael Patel

Большое спасибо за помощь, @Panos


2 ответа


Лучший ответ:

0

Главная хитрость заключается в том, чтобы понять, как работает класс Arduino String. Вы можете найти исходный код в своей установке Arduino IDE или на github.

Основной шаблон, который вам нужен:

String h(String& input) {      // Передать строку по ссылке, чтобы избежать копирования
  char output[OUTPUT_MAX];
  char* data = input.c_str();  // Доступ к внутреннему буферу
  ...
  return String(output);       // Возвращаем объект String вывода
}

Ура!

,

Спасибо, я обновил свой вопрос, пытаясь решить эту проблему, но я все еще борюсь с ошибками. Не могли бы вы помочь мне с кодом внутри, чтобы он работал?, @Panos

Да, у вас есть несколько проблем, но прежде чем продолжить, пожалуйста, подтвердите, что вы получили ответ на свой первоначальный вопрос :), и я свяжусь с вами., @Mikael Patel

ок, ладно, просто хочу полностью решить мою проблему, @Panos

Снова обновил мой код, он работает, но не выводит правильный хеш, выводит «ffe9aaeaa2a2d5048174df0b80599ef0197ec024c4b051bc9860cff58ef7f9f3» вместо «ba7816bf8f01cfea414140de5dae2223b00361a396». 177a9cb410ff61f20015ad", @Panos


1

Я предлагаю следующую функцию. Это заменяет строку ее хешем. Это сделано на месте в целях экономии памяти. Убедитесь, что буфер, который вы дайте, что он имеет длину не менее 65 байт. Внимание: не проверено.

#include <Crypto.h>
#include <SHA256.h>

#define HASH_SIZE 32

SHA256 sha256;

/*
* Замените строку ее хешем на месте.
* "данные" должны указывать на буфер длиной не менее 65 байт.
*/
hash_in_place(char *data)
{
    uint8_t value[HASH_SIZE];

    sha256.reset();
    sha256.update(data, strlen(data));
    sha256.finalize(value, sizeof(value));

    // Преобразование в шестнадцатеричный формат исходного буфера.
    data[0] = '\0';
    for (size_t i = 0; i < HASH_SIZE; i++) {
        data += sprintf("%02x", value[i]);
    }
}
,

Хорошая реализация! Можно было бы избежать sprintf(), чтобы уменьшить размер памяти программы., @Mikael Patel