Вычислить 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()
{
}
@Panos, 👍2
Обсуждение2 ответа
Лучший ответ:
Главная хитрость заключается в том, чтобы понять, как работает класс 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
Я предлагаю следующую функцию. Это заменяет строку ее хешем. Это сделано на месте в целях экономии памяти. Убедитесь, что буфер, который вы дайте, что он имеет длину не менее 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
- Преобразование строки c integer в unsigned char
- Я не могу правильно получить строку, которую я отправил через nrf
- Обновить `символ*`
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- форматирование строк в Arduino для вывода
- Очень простая операция Arduino Uno Serial.readString()
- DateTime в строку
Подсказка №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