C语言 使用 OpenSSL 计算并打印文件的 SHA256 哈希值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7853156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:57:38  来源:igfitidea点击:

Calculate and print SHA256 hash of a file using OpenSSL

ccryptographyopensslsha256

提问by dan6470

I'm trying to write a C function using OpenSSL/libcrypto to calculate the SHA256 sum of a file. I'm basing my code on Adam Lamer's c++ example here.

我正在尝试使用 OpenSSL/libcrypto 编写一个 C 函数来计算文件的 SHA256 总和。我的代码基于 Adam Lamer 的 c++ 示例here

Here's my code:

这是我的代码:

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;
}

The problem is this....take a look at the calculated sums below for an example file:

问题是这样的....看看下面的计算总和的示例文件:

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

I also get * stack smashing detected * when the code is finished executing.

当代码完成执行时,我还检测到 * stack smashing *。

Does anyone see what I'm doing wrong?

有没有人看到我做错了什么?

Thanks!

谢谢!

回答by P.T.

Looks like there are a lot of '0xff' blocks in your output, and the corresponding blocks in the good string have the high bit set ... maybe a sign extension problem somewhere.

看起来您的输出中有很多 '0xff' 块,并且好字符串中的相应块设置了高位......也许某处的符号扩展问题。

Does making:

是否制作:

char hash[SHA256_DIGEST_LENGTH];

unsigned, like:

未签名,例如:

unsigned char hash[SHA256_DIGEST_LENGTH];

help? (Especially in the signature of sha256_hash_string.)

帮助?(特别是在 . 的签名中sha256_hash_string

回答by Adam Rosenfield

You're printing out a signedcharas an integer. If the byte is negative, it get's converted to a signed int(the default argument promotionsin the call to sprintf), and then that gets converted to an unsigned int(via the %xformat specifier) and printed out.

您正在打印一个带符号char的整数。如果字节为负数,则将其转换为 a signed int(调用中的默认参数提升sprintf),然后将其转换为 an unsigned int(通过%x格式说明符)并打印出来。

So, the byte A0is -96 as a signed byte, which gets converted to -96 as a signed int, which is 0xFFFFFFA0 in hex, so it gets printed out as FFFFFFA0.

因此,该字节A0是 -96 作为有符号字节,它被转换为 -96 作为 a signed int,在十六进制中是 0xFFFFFFA0,因此它被打印为 FFFFFFA0。

To fix this, case each byte to an unsigned charbefore printing:

要解决此问题,请unsigned char在打印前将每个字节设置为一个:

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

You're getting the warning about stack smashing because there's a signed byte near the end of the hash, so you're writing the 8 bytes FFFFFFB7 at offset 58 when you intended to only write 2 bytes. This results in a buffer overflow, which happens to be detected here because the compiler likely inserted a guard area or security cookie in the stack before the return value, and it detected that that guard area was inadvertently modified.

您收到有关堆栈粉碎的警告,因为在散列末尾附近有一个带符号的字节,因此当您打算仅写入 2 个字节时,您正在偏移 58 处写入 8 个字节的 FFFFFFB7。这会导致缓冲区溢出,这恰好在这里被检测到,因为编译器可能在返回值之前在堆栈中插入了一个防护区或安全 cookie,并且它检测到该防护区被无意中修改了。