所以我试图编写一个对目录进行哈希处理然后输出SHA256哈希的程序/函数
我的问题是,我调用了一个遍历所有目录和子目录的函数,并将缓冲区中的所有文件送入哈希函数(基于https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program--creating-an-md-5-hash-from-file-content的哈希函数,它将打开并读取文件,然后放入缓冲区)。现在,我想我会获得所有信息的正确缓冲区,但是一旦它散列了,我就不会得到正确的哈希(我知道我拥有的另一个程序没有源代码的正确哈希)。我已经尝试过查找它,但是找不到任何可以帮助我的东西...缓冲区大小是否有问题,或者我的代码在根本上做错了什么?提前致谢! (我在编程方面还是个菜鸟)
我尝试使用更大的缓冲区,但最终得到的哈希值完全相同。
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <experimental/filesystem>
#define BUFSIZE 1024
#define SHA256LEN 32
#define PATH "C:\\SomeUser\\SomeDirectory"
using namespace std;
namespace filesys = std::experimental::filesystem;
std::vector<std::string> getAllFilesInDir(const std::string& dirPath, const std::vector<std::string> dirSkipList = { })
{
// Create a vector of string
std::vector<std::string> listOfFiles;
try {
// Check if given path exists and points to a directory
if (filesys::exists(dirPath) && filesys::is_directory(dirPath))
{
// Create a Recursive Directory Iterator object and points to the starting of directory
filesys::recursive_directory_iterator iter(dirPath);
// Create a Recursive Directory Iterator object pointing to end.
filesys::recursive_directory_iterator end;
// Iterate till end
while (iter != end)
{
// Check if current entry is a directory and if exists in skip list
if (filesys::is_directory(iter->path()) &&
(std::find(dirSkipList.begin(), dirSkipList.end(), iter->path().filename()) != dirSkipList.end()))
{
// Skip the iteration of current directory pointed by iterator
#ifdef USING_BOOST
// Boost Fileystsem API to skip current directory iteration
iter.no_push();
#else
// c++17 Filesystem API to skip current directory iteration
iter.disable_recursion_pending();
#endif
}
else
{
// Add the name in vector
listOfFiles.push_back(iter->path().string());
}
error_code ec;
// Increment the iterator to point to next entry in recursive iteration
iter.increment(ec);
if (ec) {
std::cerr << "Error While Accessing : " << iter->path().string() << " :: " << ec.message() << '\n';
}
}
}
}
catch (std::system_error& e)
{
std::cerr << "Exception :: " << e.what();
}
return listOfFiles;
}
DWORD hashDirectory()
{
DWORD dwStatus = 0;
BOOL bResult = FALSE;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
BYTE rgbFile[BUFSIZE];
DWORD cbRead = 0;
BYTE rgbHash[SHA256LEN];
DWORD cbHash = 0;
CHAR rgbDigits[] = "0123456789abcdef";
std::vector<std::string> listOfFiles = getAllFilesInDir(PATH);
for (auto str : listOfFiles)
{
if (!filesys::is_directory(str))
{
LPCSTR filename = str.c_str();
// Logic to check usage goes here.
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_AES,
CRYPT_VERIFYCONTEXT)
)
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
return dwStatus;
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 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 = SHA256LEN;
if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
//printf("SHA256 hash of file %s is: ", filename);
printf("sha256 Files:");
for (DWORD i = 0; i < cbHash; i++)
{
printf("%c%c", rgbDigits[rgbHash[i] >> 4],
rgbDigits[rgbHash[i] & 0xf]);
}
printf("\n");
}
else
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", dwStatus);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CloseHandle(hFile);
return dwStatus;
}