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

C 使用OpenSSL计算并打印文件的SHA256哈希,c,cryptography,openssl,sha256,C,Cryptography,Openssl,Sha256,我正在尝试使用OpenSSL/libcrypto编写一个C函数来计算文件的SHA256和。我把代码放在Adam Lamer的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 = fope

我正在尝试使用OpenSSL/libcrypto编写一个C函数来计算文件的SHA256和。我把代码放在Adam Lamer的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;
}
当代码完成执行时,我还检测到*堆栈崩溃*

有人知道我做错了什么吗


谢谢

看起来您的输出中有很多“0xff”块,而良好字符串中的相应块设置了高位。。。可能是某个地方的标志扩展问题

制作:

char hash[SHA256_DIGEST_LENGTH];
未签名,例如:

unsigned char hash[SHA256_DIGEST_LENGTH];
帮忙?(特别是在签名为
sha256\u hash\u string
时)

将签名的
char
打印为整数。如果字节为负数,则将其转换为
有符号int
(调用
sprintf
时的默认参数),然后将其转换为
无符号int
(通过
%x
格式说明符)并打印出来

因此,字节
A0
作为有符号字节为-96,转换为-96作为
signed int
,十六进制为0xFFFF0,因此打印为FFFFFFA0

要解决此问题,请在打印前将每个字节的大小写转换为无符号字符:

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

您将收到有关堆栈崩溃的警告,因为哈希末尾附近有一个带符号的字节,因此您正在偏移量58处写入8字节FFFFFFB7,而您只打算写入2字节。这会导致出现一个错误,因为编译器可能在返回值之前在堆栈中插入了一个保护区域或安全cookie,并且检测到该保护区域被无意中修改。

修复了它!非常感谢。我在Ubuntu上使用gcc。我对little endianess的评论是错误的,所以我删除了它。。。Adam对每次输入为负数时打印8个字节有正确的解释。这是一个很好的例子,说明了为什么在处理“字节”而不是“字符串”时,应该使用“unsigned char”(或uint8或其变体之一)。空的“char”应该保留给ASCII字符。就是这样!谢谢你的解释!!为什么const int bufSize的大小固定为32768?可能或多或少
sprintf(..., (unsigned char)hash[i]);