Рассчитать и распечатать SHA256 хеш файла с помощью OpenSSL

c cryptography openssl sha256

27808 просмотра

2 ответа

Я пытаюсь написать функцию C, используя OpenSSL / libcrypto для вычисления суммы SHA256 файла. Я основывая свой код на Адама ламер в C ++ , например здесь .

Вот мой код:

int main (int argc, char** argv)
{
    char calc_hash[65];

    calc_sha256("file.txt", calc_hash);
}

int calc_sha256 (char* path, char output[65])
{
    FILE* file = fopen(path, "rb");
    if(!file) return -1;

    char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    const int bufSize = 32768;
    char* buffer = malloc(bufSize);
    int bytesRead = 0;
    if(!buffer) return -1;
    while((bytesRead = fread(buffer, 1, bufSize, file)))
    {
        SHA256_Update(&sha256, buffer, bytesRead);
    }
    SHA256_Final(hash, &sha256);

    sha256_hash_string(hash, output);
    fclose(file);
    free(buffer);
    return 0;
}      

void sha256_hash_string (char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65])
{
    int i = 0;

    for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
    }

    outputBuffer[64] = 0;
}

Проблема заключается в следующем ... взгляните на расчетные суммы ниже для примера файла:

Known good SHA256: 6da032d0f859191f3ec46a89860694c61e65460d54f2f6760b033fa416b73866
Calc. by my code:  6dff32ffff59191f3eff6affff06ffff1e65460d54ffff760b033fff16ff3866

Я также получаю * обнаружение разрушения стека * по завершении выполнения кода.

Кто-нибудь видит, что я делаю не так?

Спасибо!

Автор: dan6470 Источник Размещён: 12.11.2019 09:24

Ответы (2)


14 плюса

Решение

Похоже, в вашем выводе много блоков '0xff', и соответствующие блоки в хорошей строке имеют старший бит ... может быть, где-то проблема расширения знака.

Делает ли:

char hash[SHA256_DIGEST_LENGTH];

без знака, как:

unsigned char hash[SHA256_DIGEST_LENGTH];

Помогите? (Особенно в подписи sha256_hash_string.)

Автор: P.T. Размещён: 21.10.2011 05:53

11 плюса

Вы распечатываете подписанное char целое число. Если байт отрицательный, он преобразуется в signed int( аргумент по умолчанию в вызове sprintf), а затем преобразуется в unsigned int(через %xспецификатор формата) и распечатывается.

Таким образом, байт A0является -96 как байт со знаком, который преобразуется в -96 как a signed int, что равно 0xFFFFFFA0 в шестнадцатеричном формате, поэтому он печатается как FFFFFFA0.

Чтобы это исправить, поместите каждый байт unsigned charперед печатью:

sprintf(..., (unsigned char)hash[i]);

Вы получаете предупреждение о разрушении стека, потому что рядом с концом хеша есть подписанный байт, поэтому вы записываете 8-байтовый FFFFFFB7 со смещением 58, когда вы намеревались записать только 2 байта. Это приводит к переполнению буфера , которое здесь обнаруживается, потому что компилятор, вероятно, вставил защитную область или файл cookie безопасности в стек перед возвращаемым значением, и обнаружил, что эта защитная область была случайно изменена.

Автор: Adam Rosenfield Размещён: 21.10.2011 05:54
Вопросы из категории :
32x32