【问题标题】:Calculate and print SHA256 hash of a file using OpenSSL使用 OpenSSL 计算并打印文件的 SHA256 哈希
【发布时间】:2011-12-12 18:45:03
【问题描述】:

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

这是我的代码:

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

当代码完成执行时,我还得到 * 检测到堆栈粉碎。

有人看到我做错了吗?

谢谢!

【问题讨论】:

  • 为什么 const int bufSize 的大小固定为 32768 ?它可能或多或少

标签: c cryptography openssl sha256


【解决方案1】:

看起来你的输出中有很多'0xff'块,并且好字符串中的相应块设置了高位......可能是某个地方的符号扩展问题。

制作:

char hash[SHA256_DIGEST_LENGTH];

无符号,如:

unsigned char hash[SHA256_DIGEST_LENGTH];

帮助? (特别是sha256_hash_string的签名。)

【讨论】:

  • 解决了!谢谢!我在 Ubuntu 上使用 gcc。
  • 我关于 little-endianess 的评论是错误的,所以我删除了它......亚当对每次输入为负时打印 8 个字节的正确解释。这是一个很好的例子,说明为什么在处理“字节”而不是“字符串字符”时应该使用“无符号字符”(或 uint8 或其变体之一)。裸 'char' 应该为 ASCII 字符保留。
【解决方案2】:

您将 signed char 打印为整数。如果该字节为负数,则将其转换为signed int(在对sprintf 的调用中的默认参数promotions),然后将其转换为unsigned int(通过@987654326 @格式说明符)并打印出来。

所以,字节A0是-96作为有符号字节,它被转换为-96作为signed int,即十六进制的0xFFFFFFA0,所以它被打印为FFFFFFA0。

要解决此问题,请在打印前将每个字节大小写为 unsigned char

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

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

【讨论】:

  • 就是这样!谢谢你的解释!!
猜你喜欢
  • 2016-04-11
  • 2014-01-14
  • 1970-01-01
  • 2013-11-12
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
相关资源
最近更新 更多