gpt4 book ai didi

c - hashResult 变量没有存储正确的值

转载 作者:太空宇宙 更新时间:2023-11-04 04:26:25 25 4
gpt4 key购买 nike

我有一个从文件生成散列键的程序。例如,程序的结果是 "hash of file c:\Users\Jax\Desktop\files\file.txt is: 4db5a10d2ea73e3f76"

我有一个变量,它具有此 file.txt 的预期哈希值:

char hashExpected   = "4db5a10d2ea73e3f76";

在代码的特定部分,我正在验证程序的结果哈希值是否等于存储在 hashExpected 变量中的哈希值。我有这个像下面。我有 hashResult 变量存储结果哈希,这样我就可以进行比较。但它不能正常工作,因为它总是显示 Hash is different 即使它是相等的。 hashResult 变量似乎没有存储正确的值。

        for (i = 0; i < cbHash; i++)
{
printf("%c%c",
rgbDigits[rgbHash[i] >> 4],
rgbDigits[rgbHash[i] & 0xf]);
hashResult[i] = rgbDigits[rgbHash[i] >> 4];
hashResult[i] += rgbDigits[rgbHash[i] & 0xf];
}
if (verify(hashResult, hashExpected))
{
printf("Hash is the same\n");
}
else
{
printf("Hash is different\n");
}

完整程序:

#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <stdbool.h>
#define BUFSIZE 1024
#define MD5LEN 16

bool verify(char array1[], char array2[])
{
int i;
for (i = 0; array1[i] && array2[i]; ++i)
{
if (array1[i] != array2[i])
{
return false;
}
}
return true;
}
DWORD main()
{
DWORD dwStatus = 0;
BOOL bResult = FALSE;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
BYTE rgbFile[BUFSIZE];
DWORD cbRead = 0;
BYTE rgbHash[MD5LEN];
DWORD cbHash = 0;
CHAR rgbDigits[] = "0123456789abcdef";
PCSTR filename = "c:\\Users\\Jax\\Desktop\\files\\file.txt";
char hashActual[] = "4db5a10d2ea73e3f76";
char hashExpected[] = "4db5a10d2ea73e3f76";
char hashWrong[] = "0a0a0a0a0a0a0a";
char hashResult[] = "";
hFile = CreateFile(filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);


if (INVALID_HANDLE_VALUE == hFile)
{
dwStatus = GetLastError();
printf("Error opening file %s\nError: %d\n", filename,
dwStatus);
return dwStatus;
}


// Get handle to the crypto provider
if (!CryptAcquireContext(&hProv,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
return dwStatus;
}


if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
CryptReleaseContext(hProv, 0);
return dwStatus;
}


while (bResult = ReadFile(hFile, rgbFile, BUFSIZE,
&cbRead, NULL))
{
if (0 == cbRead)
{
break;
}


if (!CryptHashData(hHash, rgbFile, cbRead, 0))
{
dwStatus = GetLastError();
printf("CryptHashData failed: %d\n", dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return dwStatus;
}
}


if (!bResult)
{
dwStatus = GetLastError();
printf("ReadFile failed: %d\n", dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return dwStatus;
}


cbHash = MD5LEN;


if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
DWORD i;

printf("MD5 hash of file %s is: ", filename);
for (i = 0; i < cbHash; i++)
{
printf("%c%c",
rgbDigits[rgbHash[i] >> 4],
rgbDigits[rgbHash[i] & 0xf]);
hashResult[i] = rgbDigits[rgbHash[i] >> 4];
hashResult[i] += rgbDigits[rgbHash[i] & 0xf];


}
if (verify(hashResult, hashExpected))
{
printf("Hash is the same\n");
}
else
{
printf("Hash is different\n");
}
}
else
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", dwStatus);
}


CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CloseHandle(hFile);


return dwStatus;
}

最佳答案

char hashExpected[] = "4db5a10d2ea73e3f76";

上面的MD5值是错误的。 MD5 值的长度为 16 个字节。但这只是字节数。我们不能在屏幕上打印字节,因此我们经常将字节转换为十六进制值。例如,如果我们有 unsinged char bytes[3] = {0x01,0x01,0xFF},我们将字节转换为十六进制字符串,它变成 "0102FF"

请注意,字符串表示形式加了一个空终止符两倍长。 MD5 散列的例子是:

"C4CA4238A0B923820DCC509A6F75849B"

字符串的缓冲区大小应为 33 (16 x 2 + 1)

要找到正确的 hashExpected,请搜索 “在线 MD5 计算器”。您可以使用http://onlinemd5.com/之类的网站来计算文件的MD5。

或者使用内容为1的文件。 MD5("1")"C4CA4238A0B923820DCC509A6F75849B",将其用作预期的哈希值。

char hashResult[] = "";

上面一行是一个编程错误,正如@melpomene 在评论中提到的

hashResult[i] = rgbDigits[rgbHash[i] >> 4];
hashResult[i] += rgbDigits[rgbHash[i] & 0xf];

上面的代码是错误的,你需要这个:

char hashResult[MD5LEN * 2 + 1] = "";
...
hashResult[i * 2] = rgbDigits[rgbHash[i] >> 4];
hashResult[i * 2 + 1] = rgbDigits[rgbHash[i] & 0xf];

verify 函数也存在问题,因为它比较错误的字节表示形式的 MD5 和错误的字符串表示形式的 MD5。

您可以使用strcmp_stricmp 来比较字符串表示中的MD5 值。或者使用memcmp(data1, data2, 16)直接比较字节。

完整示例:

#define BUFSIZE 1024
#define MD5LEN 16

int main()
{
DWORD dwStatus = 0;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
BYTE rgbFile[BUFSIZE];
DWORD cbRead = 0;
BYTE rgbHash[MD5LEN];
DWORD cbHash = 0;
CHAR rgbDigits[] = "0123456789abcdef";
PCSTR filename = "c:\\Users\\Jax\\Desktop\\files\\file.txt";

//assuming content of file.txt is '1'
char hashExpected[] = "C4CA4238A0B923820DCC509A6F75849B";

char hashResult[MD5LEN * 2 + 1] = "";
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if(INVALID_HANDLE_VALUE == hFile)
{
dwStatus = GetLastError();
printf("Error opening file %s\nError: %d\n", filename, dwStatus);
return (int)dwStatus;
}

// Get handle to the crypto provider
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
return (int)dwStatus;
}

if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
CryptReleaseContext(hProv, 0);
return (int)dwStatus;
}

while(ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
{
if(0 == cbRead)
break;

if(!CryptHashData(hHash, rgbFile, cbRead, 0))
{
dwStatus = GetLastError();
printf("CryptHashData failed: %d\n", dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return (int)dwStatus;
}
}

cbHash = MD5LEN;

if(CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
DWORD i;

printf("MD5 expected, versus MD5 of file %s is:\n", filename);
printf("%s\n", hashExpected);
for(i = 0; i < cbHash; i++)
{
printf("%c%c",
rgbDigits[rgbHash[i] >> 4],
rgbDigits[rgbHash[i] & 0xf]);
hashResult[i * 2] = rgbDigits[rgbHash[i] >> 4];
hashResult[i * 2 + 1] = rgbDigits[rgbHash[i] & 0xf];
}
printf("\n");

if(_strcmpi(hashResult, hashExpected) == 0)
printf("Hash is the same\n");
else
printf("Hash is different\n");
}
else
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", dwStatus);
}

CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CloseHandle(hFile);

return (int)dwStatus;
}

关于c - hashResult 变量没有存储正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40963069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com