我有一个从文件生成哈希键的程序。并且还验证结果散列是否等于预期散列。但该程序每次只处理一个文件。现在,我试图从给定目录中的每个文件生成一个哈希键,并与每个预期的哈希进行比较。
为此,我有以下代码来阅读目录。但我没有成功将预期的哈希与我在目录中的每个文件相关联。
使用strcmp
我可以比较并且它已经在工作,但是如何将正确的预期哈希与相应的文件相关联?你知道怎么做吗?
PCSTR text = "C:\\Users\\Jax\\Desktop\\files\\files2\\txt_1.txt";
PCSTR pptx = "C:\\Users\\Jax\\Desktop\\files\\files2\\Test.pptx";
DIR *d;
d = opendir("C:\\Users\\Jax\\Desktop\\files\\files2\\");
struct dirent *dir;
char name[256][256];
int count = 0;
int index = 0;
char TextExpected[] = "811676652bf08c0a91a849d66bb2a46c";
char PptxExpected[] = "b011367338c3264f1f3f74107060d788";
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
strcpy(name[count],dir->d_name);
count++;
if(strcmp(dir->d_name,"test.pptx") == 0){
// how can I do here to associate the hashExpected to the file "test.pptx"
}
if(strcmp(dir->d_name,"test.txt") == 0){
// how can I do here to associate the hashExpected to the file "test.txt"
}
}
closedir(d);
while( count > 0 )
{
...
在while(count> 0)内部,我执行代码为目录中的每个文件生成哈希键(count> 0)。
这是完整的程序,它只是关联部分我没有成功地让它工作:
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <dirent.h>
#include <stdbool.h>
#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 text = "C:\\Users\\Jax\\Desktop\\files\\files2\\txt_1.txt";
PCSTR pptx = "C:\\Users\\Jax\\Desktop\\files\\files2\\Test.pptx";
DIR *d;
d = opendir("C:\\Users\\Jax\\Desktop\\files\\files2\\");
struct dirent *dir;
struct dirent *test;
char name[256][256];
int count = 0;
int index = 0;
int expected[25];
int countcount;
char testtest[256][256];
char TextExpected[] = "811676652bf08c0a91a849d66bb2a46c";
char PptxExpected[] = "b011367338c3264f1f3f74107060d788";
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
strcpy(name[count],dir->d_name);
count++;
if(strcmp(dir->d_name,"test.pptx") == 0){
// how can I do here to associate the hashExpected to the file "test.pptx"
}
if(strcmp(dir->d_name,"test.txt") == 0){
// how can I do here to associate the hashExpected to the file "test.txt"
}
}
closedir(d);
while( count > 0 )
{
bool incorrect = FALSE;
char hashResult[MD5LEN * 2 + 1] = "";
hFile = CreateFile(text, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
incorrect = TRUE;
dwStatus = GetLastError();
printf("Error opening file %s\nError: %d\n", text, 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", text);
printf("%s\n", TextExpected);
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, TextExpected) == 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;
}
}
答案 0 :(得分:0)
strcpy(name[count],dir->d_name);
d_name
是相对文件名,例如"test.txt"
,但很可能您希望将完整路径名用于crypt函数。请改用完整路径。例如:
strcpy(name[count],"c:\\dir\\");
strcat(name[count],dir->d_name);
readdir
的结果包括基本没用的"."
和".."
,你想跳过它们:
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..") == 0)
continue;
while( count > 0 )
将代码置于无限循环中。你的意思是这样做:
int index = 0;
while( index < count )
{
const char* filename = name[index];
index++;
}
注意,您要使用name[index]
而非name
。
最后,添加一个函数,该函数将查找已知文件的expect哈希值。例如:
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <dirent.h>
#include <stdbool.h>
#define BUFSIZE 1024
#define MD5LEN 16
const char* get_expected_hash(const char* filename)
{
PCSTR text = "C:\\Users\\Jax\\Desktop\\files\\files2\\txt_1.txt";
PCSTR pptx = "C:\\Users\\Jax\\Desktop\\files\\files2\\Test.pptx";
const char* TextExpected = "811676652bf08c0a91a849d66bb2a46c";
const char* PptxExpected = "b011367338c3264f1f3f74107060d788";
if (stricmp(filename, text) == 0)
return TextExpected;
if (stricmp(filename, pptx) == 0)
return PptxExpected;
return "unknown hash";
}
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";
//const char* dirname = "C:\\Users\\Jax\\Desktop\\files\\files2\\";
const char* dirname = "c:\\test\\";
DIR *d;
d = opendir(dirname);
struct dirent *dir;
char files[256][256];
int count = 0;
while ((dir = readdir(d)) != NULL)
{
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..") == 0)
continue;
strcpy(files[count],dirname);
strcat(files[count],dir->d_name);
count++;
}
closedir(d);
// Get handle to the crypto provider
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", (int)dwStatus);
CloseHandle(hFile);
return (int)dwStatus;
}
int index = 0;
while( index < count )
{
const char* filename = files[index];
index++;
printf("%s\n", filename);
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)
{
//incorrect = TRUE;
dwStatus = GetLastError();
printf("Error opening file %s\nError: %d\n", filename, (int)dwStatus);
return (int)dwStatus;
}
if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", (int)dwStatus);
CloseHandle(hFile);
CryptReleaseContext(hProv, 0);
continue;
}
while(ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
{
if(0 == cbRead)
break;
if(!CryptHashData(hHash, rgbFile, cbRead, 0))
{
dwStatus = GetLastError();
printf("CryptHashData failed: %d\n", (int)dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
continue;
}
}
cbHash = MD5LEN;
if(CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
DWORD i;
printf("MD5 expected, versus MD5 of file %s is:\n", filename);
const char* TextExpected = get_expected_hash(filename);
printf("%s\n", TextExpected);
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, TextExpected) == 0)
printf("Hash is the same\n");
else
printf("Hash is different\n");
}
else
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", (int)dwStatus);
continue;
}
CryptDestroyHash(hHash);
CloseHandle(hFile);
}
CryptReleaseContext(hProv, 0);
return 0;
}