2016-12-10 30 views
0

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

为此我有下面的代码来读取目录。但我没有成功将期望的散列值与目录中的每个文件相关联。

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[] = "abcdef"; 

    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

“* icual *”?我知道我从某个地方识别了这些代码。 (这是拼写“平等”。) – melpomene

回答

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。发生错误时,您可能不想退出循环,而是想继续。

最后,添加一个函数,它将查找已知文件的期望散列值。例如:

#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[] = "abcdef"; 

    //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; 
} 
相关问题