将值与相应的文件相关联

时间:2016-12-10 21:45:22

标签: c hash

我有一个从文件生成哈希键的程序。并且还验证结果散列是否等于预期散列。但该程序每次只处理一个文件。现在,我试图从给定目录中的每个文件生成一个哈希键,并与每个预期的哈希进行比较。

为此,我有以下代码来阅读目录。但我没有成功将预期的哈希与我在目录中的每个文件相关联。

使用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;
    }
}

1 个答案:

答案 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;
}