2016-12-04 24 views
1

ファイルからハッシュキーを生成するプログラムがあります。 たとえば、プログラムの結果は"hash of file c:\Users\Jax\Desktop\files\file.txt is: 4db5a10d2ea73e3f76"です。プログラムの結果のハッシュがと等しい場合hashResult変数に正しい値が格納されていません

char hashExpected = "4db5a10d2ea73e3f76"; 

そして、私は確認していたコードのspecifc一部で:

そして私は、このfile.txtのために予想されるハッシュ値を持つ変数を持っていますハッシュはhashExpected変数に格納されます。私はこれを以下のようにしています。私はhashResult結果ハッシュを格納する変数を持っているので、私は比較することができます。しかし、それが等しい場合でもいつもHash is differentと表示されるので、正しく動作しません。 hashResult変数が正しい値を格納していないようです。

 for (i = 0; i < cbHash; i++) 
     { 
      printf("%c%c", 
        rgbDigits[rgbHash[i] >> 4], 
        rgbDigits[rgbHash[i] & 0xf]); 
      hashResult[i] = rgbDigits[rgbHash[i] >> 4]; 
      hashResult[i] += rgbDigits[rgbHash[i] & 0xf]; 
     } 
     if (verify(hashResult, hashExpected)) 
     { 
      printf("Hash is the same\n"); 
     } 
     else 
     { 
      printf("Hash is different\n"); 
     } 

全プログラム:MD5値を超える

#include <stdio.h> 
#include <windows.h> 
#include <Wincrypt.h> 
#include <stdbool.h> 
#define BUFSIZE 1024 
#define MD5LEN 16 

bool verify(char array1[], char array2[]) 
{ 
    int i; 
    for (i = 0; array1[i] && array2[i]; ++i) 
    { 
     if (array1[i] != array2[i]) 
     { 
      return false; 
     } 
    } 
    return true; 
} 
DWORD main() 
{ 
    DWORD dwStatus = 0; 
    BOOL bResult = FALSE; 
    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 filename = "c:\\Users\\Jax\\Desktop\\files\\file.txt"; 
    char hashActual[] = "4db5a10d2ea73e3f76"; 
    char hashExpected[] = "4db5a10d2ea73e3f76"; 
    char hashWrong[] = "0a0a0a0a0a0a0a"; 
    char hashResult[] = ""; 
    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_FULL, 
          CRYPT_VERIFYCONTEXT)) 
    { 
     dwStatus = GetLastError(); 
     printf("CryptAcquireContext failed: %d\n", dwStatus); 
     CloseHandle(hFile); 
     return dwStatus; 
    } 


    if (!CryptCreateHash(hProv, CALG_MD5, 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 = MD5LEN; 


    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) 
    { 
     DWORD i; 

     printf("MD5 hash of file %s is: ", filename); 
     for (i = 0; i < cbHash; i++) 
     { 
      printf("%c%c", 
        rgbDigits[rgbHash[i] >> 4], 
        rgbDigits[rgbHash[i] & 0xf]); 
      hashResult[i] = rgbDigits[rgbHash[i] >> 4]; 
      hashResult[i] += rgbDigits[rgbHash[i] & 0xf]; 


     } 
     if (verify(hashResult, hashExpected)) 
     { 
      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 dwStatus; 
} 
+1

バッファオーバーフロー:あなたの 'hashResult'配列が一つだけの要素を持っています。範囲外の 'hashResult [i] = ...'でアクセスします。 – melpomene

答えて

0
char hashExpected[] = "4db5a10d2ea73e3f76"; 

間違っています。 MD5の値は16バイトです。しかしそれは単にバイトのためです。画面上にバイトを印刷することはできないので、バイトを16進数に変換することがよくあります。たとえば、unsinged char bytes[3] = {0x01,0x01,0xFF}がある場合、バイトを16進文字列に変換すると、"0102FF"になります。

文字列表現が2倍長く、ヌルターミネータに加えて、 MD5ハッシュの例は:stringの

"C4CA4238A0B923820DCC509A6F75849B" 

バッファサイズは、正しいhashExpectedを見つける"オンラインMD5計算機"を検索する

33(16×2 + 1)であるべきです。 http://onlinemd5.com/のようなWebサイトを使用して、ファイルのMD5を計算することができます。

または、内容が1のファイルを使用してください。 MD5("1")"C4CA4238A0B923820DCC509A6F75849B"です。これを期待されるハッシュ値として使用します。線の上

char hashResult[] = ""; 

コードの上@melpomene

hashResult[i] = rgbDigits[rgbHash[i] >> 4]; 
hashResult[i] += rgbDigits[rgbHash[i] & 0xf]; 

によってコメントで述べたように、プログラミングエラーで間違っている、あなたの代わりにこのたい:

char hashResult[MD5LEN * 2 + 1] = ""; 
... 
hashResult[i * 2] = rgbDigits[rgbHash[i] >> 4]; 
hashResult[i * 2 + 1] = rgbDigits[rgbHash[i] & 0xf]; 

をも問題があります関数verifyを使用しています。これは、バイト表現の間違ったMD5と文字列表現の間違ったMD5を比較しているためです。

strcmpまたは_stricmpを使用すると、文字列表現のMD5値を比較できます。バイトを直接比較するには、memcmp(data1, data2, 16)を使用します。

全例:

#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 filename = "c:\\Users\\Jax\\Desktop\\files\\file.txt"; 

    //assuming content of file.txt is '1' 
    char hashExpected[] = "C4CA4238A0B923820DCC509A6F75849B"; 

    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) 
    { 
     dwStatus = GetLastError(); 
     printf("Error opening file %s\nError: %d\n", filename, 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", filename); 
     printf("%s\n", hashExpected); 
     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, hashExpected) == 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

本当に詳細な説明をありがとうございます。今私はその問題を理解しています。今私はあなたの解決策をexprimentしようとしていましたが、奇妙なエラーを表示しています "エラー: ':: main'は 'int'を返す必要があります。理由が分かりますか? – Jax

+0

ありがとうございます、あなたのソリューションは動作します!詳しい説明についてはもう一度おねがいします。 – Jax

関連する問題