[英]Calculate and print SHA256 hash of a file using OpenSSL
I'm trying to write a C function using OpenSSL/libcrypto to calculate the SHA256 sum of a file. 我正在尝试使用OpenSSL / libcrypto编写一个C函数来计算文件的SHA256总和。 I'm basing my code on Adam Lamer's c++ example here . 我在我的基础上亚当拉默的C ++示例代码在这里 。
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! 谢谢!
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
的签名中。)
You're printing out a signed char
as an integer. 您将签名的 char
打印为整数。 If the byte is negative, it get's converted to a signed int
(the default argument promotions in the call to sprintf
), and then that gets converted to an unsigned int
(via the %x
format specifier) and printed out. 如果字节为负数,则将其转换为signed int
(调用sprintf
的默认参数升级 ),然后将其转换为unsigned int
(通过%x
格式说明符)并打印出来。
So, the byte A0
is -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作为有符号字节,它作为有signed int
转换为-96,十六进制为0xFFFFFFA0,因此它打印为FFFFFFA0。
To fix this, case each byte to an unsigned char
before 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. 您收到有关堆栈粉碎的警告,因为在散列末尾附近有一个带符号的字节,因此当您打算只写2个字节时,您将在偏移58处写入8个字节的FFFFFFB7。 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. 这导致缓冲区溢出 ,这恰好在这里被检测到,因为编译器可能在返回值之前在堆栈中插入了保护区域或安全cookie,并且它检测到该保护区域被无意修改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.