SHA - 程序输出不同于 sha512sum 命令

SHA - Output of program is different from sha512sum command

总而言之,我是第一次使用 openssl/sha.h 进行编程,编译时一切正常。这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <openssl/sha.h>


int main()
{
    int j;

    FILE *hash_file = fopen("hash.txt", "wb");

    for(j = 0; j < 256; j++)
    {
        unsigned char md[SHA512_DIGEST_LENGTH];
        char* fileName = malloc(sizeof(int));
        sprintf(fileName, "%X%s", j, ".txt");

        int i;
        FILE *file = fopen(fileName, "rb");
        SHA512_CTX mdcontext;

        int bytes;
        unsigned char data[2048];

        if(file == NULL)
        {
            printf("%s can not be opened\n", fileName);
            return;
        }

        SHA512_Init(&mdcontext);

        while((bytes = fread(data, 1, 2048, file) != 0))
            SHA512_Update(&mdcontext, data, bytes);

        SHA512_Final(md, &mdcontext);

        for(i = 0; i < SHA512_DIGEST_LENGTH; i++)
        {
            printf("%x", md[i]);
            fprintf(hash_file, "%x", md[i]);
        }
        // fprintf(hash_file, "\n");
        printf("\n");
        free(fileName);
        fclose(file);
    }

    fclose(hash_file);
    return 0;
}

我有这个输出:

711c22448e721e5491d8245b49425aa861f1fc4a15287f735e23799b65cffec5b5abdfddd91cd643aeb3b530d48f5e258e7e230a94ed525c1387bb4e1b  

但是当我在 Linux 中使用 sha512sum 命令散列相同的文件时,我得到了这个输出:

6e3ea4bec3cd738f06f011c2f4ee4f6cd6d12205cafe41c083d52f94d9de4ab8b9e702664a367b633be14024a96e88a140a2e7fee4dc2c6e2f0bd436e281e35b  make.sh  

有什么问题?

天呐!

一个小小的括号可以让你拔出你的头发。

问题出在这条语句while((bytes = fread(data, 1, 2048, file) != 0))。你看,在这个语句中 != 条件将首先被评估。因此,当 fread 读取(和 returns)时,假设 n 个字符,它会检查是否 n!=0。如果计算结果为 true,则将 bytes 设置为 1true 转换为 1)。

而现在,函数 SHA512_Update(&mdcontext, data, bytes); 变成了 SHA512_Update(&mdcontext, data, 1); 而它应该是 SHA512_Update(&mdcontext, data, n); (其中 n 是成功读取的字符数)。

解决方案

while((bytes = fread(data, 1, 2048, file) != 0)) 更改为 while((bytes = fread(data, 1, 2048, file)) != 0)

更新[将散列保存在char数组中]:

SHA512 的输出是 128 个字符。因此,我们需要一个 char 数组,其大小是 SHA512_DIGEST_LENGTH (64) 的两倍。然后,我们可以使用 sprintf.

将其存储在 char 数组中
char hash[SHA512_DIGEST_LENGTH*2];
for(i = 0; i < SHA512_DIGEST_LENGTH; i++)
    sprintf(&hash[i*2], "%02x", md[i]);

为什么i*2?因为输出的宽度为 2 个字节。因此,结果将存储在 hash[i]hash[i+1].

现在,打印它:

for(i = 0; i < SHA512_DIGEST_LENGTH*2; i++)
    printf("%c", hash[i]);

PS: 了解 precedence

并且不要忘记遵循您的 post 评论中的建议,尤其是史蒂夫关于使用 %02x 的建议。