如何使用Wincrypt获取正确的目录SHA256哈希

时间:2019-07-12 08:03:59

标签: c++ windows hash sha256 wincrypt

所以我试图编写一个对目录进行哈希处理然后输出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;
}

0 个答案:

没有答案