使用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 = 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
当代码执行完毕后,我也会检测到* stack smashing *。
有谁看到我做错了什么?
谢谢!
看起来你的输出中有很多’0xff’块,并且好字符串中的相应块有高位设置…可能是某处的符号扩展问题。
制作:
char hash[SHA256_DIGEST_LENGTH];
无符号的,如:
unsigned char hash[SHA256_DIGEST_LENGTH];
救命? (特别是在sha256_hash_string
的签名中。)
您将签名的 char
打印为整数。 如果字节为负数,则将其转换为signed int
(调用sprintf
的默认参数promotion ),然后将其转换为unsigned int
(通过%x
格式说明符)并打印出来。
因此,字节A0
是-96作为有符号字节,它作为有signed int
转换为-96,hex为0xFFFFFFA0,因此它打印为FFFFFFA0。
要解决此问题,请在打印前将每个字节写入unsigned char
:
sprintf(..., (unsigned char)hash[i]);
您收到有关堆栈粉碎的警告,因为在散列末尾附近有一个带符号的字节,因此当您打算只写2个字节时,您将在偏移58处写入8个字节的FFFFFFB7。 这导致缓冲区溢出 ,这恰好在这里被检测到,因为编译器可能在返回值之前在堆栈中插入了保护区域或安全cookie,并且它检测到该保护区域被无意修改。