esp_partition_get_sha256() не соответствует функции PHP hash() в HTTPUpdate

Отказ от ответственности: возможно, этот вопрос относится к форуму PHP, а не к этому. Однако этот вопрос также очень связан с ESP32/Arduino. Пожалуйста, поправьте меня, если это так.

Сценарий:

  • Реализация процедур автоматического обновления для моего проекта ESP32 с использованием HTTPUpdate Использование PHP-скрипта на стороне сервера, чтобы решить, какое двоичное изображение передать на устройство, или вернуть код возврата HTTP 304, если обновления недоступны.
  • Использование хэшей MD5 и SHA-256 скетча, предоставленных библиотекой HTTPUpdate, в качестве заголовков запросов на стороне сервера для проверки двоичной версии.

Проблема:

  • Хэш MD5, содержащийся в заголовке запроса "x-ESP32-sketch-md5", такой же, как и хэш MD5, рассчитанный простым вызовом md5() с использованием необработанный двоичный файл для текущей версии.
  • Хэш SHA256, содержащийся в заголовке запроса "x-ESP32-sketch-sha256", отличается от хэша, полученного при вызове функции PHP hash("sha256", $v) (где $v содержит тот же необработанный двоичный файл).

Пример:

  • MD5 (HTTPUpdate): c93d814989b53a24a0164e561b6a8bf8
  • MD5 (PHP): c93d814989b53a24a0164e561b6a8bf8 (без разницы)
  • SHA256 (HTTPUpdate): 5634674253E095600CD863A34287FCA742BCFCF9B5BF409870DD65AF0ADEF7A0
  • SHA256 (PHP): 1ECDDF3215520C79AAD13BBC1D116D9286910490DF316B9B203FCBFC89CBCCC2 (другой)

Я делаю что-то не так?

Примечание. Функция esp_partition_get_sha256() вызывается внутри методом update() библиотеки HTTPUpdate.

Код PHP (для расчета хэшей):

<?php

$v = file_get_contents("fw.bin");

print("MD5: ". md5($v)."\r\n");
print("SHA256: ".hash("sha256", $v)."\r\n");

Код Arduino (соответствующая часть):

// Вызывается один или два раза в день
void update_fw()
{
    Serial.println("Checking for updates...");

    t_httpUpdate_return ret = httpUpdate.update(client, "http://my_server/fw/check_fw.php"); // На данный момент он регистрирует только заголовки и возвращает код HTTP 304

    switch (ret)
    {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }
}

Код PHP (регистрирует заголовки и возвращает код HTTP 304):

<?php

$headers = getallheaders();

if (!file_exists("log.txt"))
{
    file_put_contents("log.txt", print_r($headers, true));
}

http_response_code(304);            // Нет обновлений.

exit;

Заранее спасибо.

, 👍0


1 ответ


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

1

Ваша проблема связана с непониманием того, что делают функции.

Ваши хэши MD5 — это хеш самого двоичного файла. И поэтому они совпадают.

Ваш PHP SHA256 – это хэш двоичного файла (например, MD5), а SHA256 ESP – нет.

Сам файл содержит хэш SHA256 содержимого файла, а не всего файла. Функция esp_partition_get_sha256 просто возвращает этот хэш SHA256.

Согласно документации SDK:

Для приложений с SHA-256, добавленным к изображению приложения, результатом является добавленное значение SHA-256 для содержимого изображения приложения. Хэш проверяется перед возвратом, если содержимое приложения недействительно, функция возвращает ESP_ERR_IMAGE_INVALID. Для приложений без добавления SHA-256 к изображению результатом является SHA-256 всех байтов в образе приложения. Для других типов разделов результатом является SHA-256 всего раздела.

Если вы возьмете двоичный файл и каким-то образом удалите лишнюю информацию sha256, а затем выполните хеширование результатов, вы должны (теоретически) получить тот же хеш, который будет таким же, как и в самом файле. .

,

Истинный. Я пришел к тому же выводу совершенно другим путем. Следуя наитию, я открыл файл в шестнадцатеричном редакторе и сразу распознал в конце знакомые байты. Не что-то очень научное, но, увы, они были. Хотя мое исследование могло бы быть более тщательным, я частично виню в этом отсутствие комментариев и документации в коде, а также довольно скудную (недоступную для поиска) документацию по проекту Arduino-ESP32. Может, пора и мне внести свой вклад? О, и спасибо., @Flyingfenix

Чтобы "каким-то образом убрать лишний SHA256": `$image = substr($old_image,0, -32);`., @Flyingfenix