2016-12-10 89 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; 
} 
相關問題