Неправильный хэш MD5

Тема в разделе "WASM.BEGINNERS", создана пользователем verelex, 12 ноя 2009.

  1. verelex

    verelex New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    90
    Из википедии:
    MD5("md5") = 1bc29b36f623ba82aaf6724fd3b16718
    MD5("md4") = c93d3bf7a7c4afe94b64e30c2ce39f4f
    MD5("") = d41d8cd98f00b204e9800998ecf8427e

    Уменя получилось:
    MD5("md5") = 8972340305b0d53ba4492ac367424f3e
    MD5("md4") = 8972340305b0d53ba4492ac367424f3e
    MD5("") = d41d8cd98f00b204e9800998ecf8427e - сходится

    Реализовывал двумя способами и получается, что последняя буква в строке не играет роли. А если строка большая, то несколько последних букв любые с итоговым одинаковым хэшем. Где ошибка?
     
  2. verelex

    verelex New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    90
    void Ccrypt_hashDlg::OnBnClickedButton1()
    {
    // Declare and initialize variables.
    HCRYPTPROV hCryptProv = NULL; // handle for a cryptographic provider context
    PTCHAR UserName = L"MyKeyContainer"; // name of the key container to be used
    // Attempt to acquire a context and a key
    // container. The context will use the default CSP
    // for the RSA_FULL provider type. DwFlags is set to zero
    // to attempt to open an existing key container.
    if(CryptAcquireContext(&hCryptProv,UserName,NULL,PROV_RSA_FULL,0))
    {
    MessageBox(UserName,L"context has been acquired");
    }
    else
    {
    // An error occurred in acquiring the context. This could mean
    // that the key container requested does not exist. In this case,
    // the function can be called again to attempt to create a new key
    // container. Error codes are defined in Winerror.h.
    if(GetLastError() == NTE_BAD_KEYSET)
    {
    if(CryptAcquireContext(&hCryptProv,UserName,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET))
    {
    MessageBox(L"A new key container has been created");
    }
    else
    {
    MessageBox(L"Could not create a new key container");
    return;
    }
    }
    else
    {
    MessageBox(L"A cryptographic service handle could not be acquired");
    return;
    }
    }
    // A cryptographic context and a key container are available.
    // Acquire a hash object handle.
    HCRYPTHASH hOriginalHash;
    if(CryptCreateHash(hCryptProv,CALG_MD5,0,0,&hOriginalHash))
    {
    MessageBox(L"An empty hash object has been created");
    }
    else
    {
    MessageBox(L"Error during CryptCreateHash()");
    return;
    }

    UpdateData(); // текст из Edit1 в m_Str
    BYTE *pbBuffer = (BYTE*)m_Str.GetBuffer();//(BYTE *)"The data that is to be hashed and signed.";
    DWORD dwBufferLen = m_Str.GetLength();//strlen((char *)pbBuffer)+1;

    if(CryptHashData(hOriginalHash,pbBuffer,dwBufferLen,0))
    {
    MessageBox(L"The data buffer has been added to the hash");
    }
    else
    {
    MessageBox(L"Error during CryptHashData()");
    return;
    }
    // At this point, the content of pbBuffer has been added to the hash.
    // Additional data can be added by repeatedly calling CryptHashData.

    Get_And_Print_Hash(hOriginalHash);

    // After processing, hCryptProv and hHash must be released.
    if(hOriginalHash) CryptDestroyHash(hOriginalHash);

    // When the handle is no longer needed, it must be released.
    if(hCryptProv)
    {
    if(CryptReleaseContext(hCryptProv,0))
    {
    MessageBox(L"The handle has been released");
    }
    else
    {
    MessageBox(L"The handle could not be released");
    }
    }
    }

    //--------------------------------------------------------------------
    void Ccrypt_hashDlg::Get_And_Print_Hash(HCRYPTHASH hOHash)
    {
    HCRYPTHASH hHash;
    BYTE *pbHash;
    BYTE *pbHashSize;
    DWORD dwHashLen = sizeof(DWORD);
    // Duplicate the hash passed in.
    // The hash is duplicated to leave the original hash intact.
    if(!CryptDuplicateHash(hOHash,NULL,0,&hHash))
    {
    MessageBox(L"Error during CryptDuplicateHash()");
    return;
    }

    if(!(pbHashSize =(BYTE *) malloc(dwHashLen)))
    {
    MessageBox(L"Memory allocation failed");
    return;
    }

    if(CryptGetHashParam(hHash,HP_HASHSIZE,pbHashSize,&dwHashLen,0))
    {
    free(pbHashSize);
    }
    else
    {
    MessageBox(L"CryptGetHashParam failed to get size");
    return;
    }

    if(!CryptGetHashParam(hHash,HP_HASHVAL,NULL,&dwHashLen,0))
    {
    MessageBox(L"CryptGetHashParam failed to get length");
    return;
    }

    pbHash = (BYTE*)malloc(dwHashLen);
    if(!pbHash)
    {
    MessageBox(L"Allocation failed");
    return;
    }

    if(CryptGetHashParam(hHash,HP_HASHVAL,pbHash,&dwHashLen,0))
    {
    // Print the hash value
    char tmp[32];
    char buf[128];
    RtlZeroMemory(tmp,32);
    RtlZeroMemory(buf,128);
    // Bytes to string
    for(int i=0; i<dwHashLen; i++)
    {
    //_itoa_s(pbHash,tmp,32,10);
    wsprintfA(tmp,"%2.2x",pbHash);
    lstrcatA(buf,tmp);
    //lstrcatA(buf,",");
    }
    //MessageBoxA(0,buf,"Hash",MB_OK);
    SetWindowTextA((GetDlgItem(IDC_EDIT2))->m_hWnd,(LPCSTR)buf);
    }
    else
    {
    MessageBox(L"Error during reading hash value.");
    return;
    }
    free(pbHash);

    if(!CryptDestroyHash(hHash))
    {
    MessageBox(L"ERROR - CryptDestroyHash()");
    }
    }
     
  3. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    в твоём коде конечно.
     
  4. verelex

    verelex New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    90
    Код (Text):
    1. /* md5.h - header file for md5.c */
    2. /* RSA Data Security, Inc., MD5 Message-Digest Algorithm */
    3.  
    4. /* NOTE: Numerous changes have been made; the following notice is
    5. included to satisfy legal requirements.
    6.  
    7. Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
    8. rights reserved.
    9.  
    10. License to copy and use this software is granted provided that it
    11. is identified as the "RSA Data Security, Inc. MD5 Message-Digest
    12. Algorithm" in all material mentioning or referencing this software
    13. or this function.
    14.  
    15. License is also granted to make and use derivative works provided
    16. that such works are identified as "derived from the RSA Data
    17. Security, Inc. MD5 Message-Digest Algorithm" in all material
    18. mentioning or referencing the derived work.
    19.  
    20. RSA Data Security, Inc. makes no representations concerning either
    21. the merchantability of this software or the suitability of this
    22. software for any particular purpose. It is provided "as is"
    23. without express or implied warranty of any kind.
    24.  
    25. These notices must be retained in any copies of any part of this
    26. documentation and/or software.
    27. */
    28. #pragma once
    29.  
    30. #ifndef H__MD5
    31. #define H__MD5
    32.  
    33. typedef unsigned long UINT4;
    34.  
    35. typedef struct
    36. {
    37.   UINT4 state[4];
    38.   UINT4 count[2];
    39.   unsigned char buffer[64];
    40. } MD5;
    41.  
    42. void MD5Open(MD5 *);
    43. void MD5Digest(MD5 *, const void *, unsigned int);
    44. void MD5Close(MD5 *, unsigned char[16]);
    45. #endif
    46.  
    47.  
    48. /* md5.c - RSA Data Security, Inc., MD5 Message-Digest Algorithm */
    49.  
    50. /* NOTE: Numerous changes have been made; the following notice is
    51. included to satisfy legal requirements.
    52.  
    53. Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
    54. rights reserved.
    55.  
    56. License to copy and use this software is granted provided that it
    57. is identified as the "RSA Data Security, Inc. MD5 Message-Digest
    58. Algorithm" in all material mentioning or referencing this software
    59. or this function.
    60.  
    61. License is also granted to make and use derivative works provided
    62. that such works are identified as "derived from the RSA Data
    63. Security, Inc. MD5 Message-Digest Algorithm" in all material
    64. mentioning or referencing the derived work.
    65.  
    66. RSA Data Security, Inc. makes no representations concerning either
    67. the merchantability of this software or the suitability of this
    68. software for any particular purpose. It is provided "as is"
    69. without express or implied warranty of any kind.
    70.  
    71. These notices must be retained in any copies of any part of this
    72. documentation and/or software.
    73. */
    74.  
    75. //#include <memory.h>
    76. #include "stdafx.h"
    77. #include "md5.h"
    78. #define LITTLE_ENDIAN 1
    79.  
    80. void MD5Open(MD5 *md5)
    81. {
    82.   md5->count[0] = md5->count[1] = 0;
    83.   /* Load magic initialization constants.*/
    84.   md5->state[0] = 0x67452301;
    85.   md5->state[1] = 0xefcdab89;
    86.   md5->state[2] = 0x98badcfe;
    87.   md5->state[3] = 0x10325476;
    88. }
    89.  
    90. /* Constants for MD5Transform routine. */
    91.  
    92. #define S11 7
    93. #define S12 12
    94. #define S13 17
    95. #define S14 22
    96. #define S21 5
    97. #define S22 9
    98. #define S23 14
    99. #define S24 20
    100. #define S31 4
    101. #define S32 11
    102. #define S33 16
    103. #define S34 23
    104. #define S41 6
    105. #define S42 10
    106. #define S43 15
    107. #define S44 21
    108.  
    109. /* F, G, H and I are basic MD5 functions. */
    110.  
    111. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
    112. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
    113. #define H(x, y, z) ((x) ^ (y) ^ (z))
    114. #define I(x, y, z) ((y) ^ ((x) | (~z)))
    115.  
    116. /* ROTATE_LEFT rotates x left n bits. */
    117.  
    118. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
    119.  
    120. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
    121.    Rotation is separate from addition to prevent recomputation.
    122. */
    123.  
    124. #define FF(a, b, c, d, x, s, ac) { \
    125.  (a) += F((b), (c), (d)) + (x) + (UINT4)(ac); \
    126.  (a) = ROTATE_LEFT((a), (s)); \
    127.  (a) += (b); \
    128.   }
    129. #define GG(a, b, c, d, x, s, ac) { \
    130.  (a) += G((b), (c), (d)) + (x) + (UINT4)(ac); \
    131.  (a) = ROTATE_LEFT((a), (s)); \
    132.  (a) += (b); \
    133.   }
    134. #define HH(a, b, c, d, x, s, ac) { \
    135.  (a) += H((b), (c), (d)) + (x) + (UINT4)(ac); \
    136.  (a) = ROTATE_LEFT((a), (s)); \
    137.  (a) += (b); \
    138.   }
    139. #define II(a, b, c, d, x, s, ac) { \
    140.  (a) += I((b), (c), (d)) + (x) + (UINT4)(ac); \
    141.  (a) = ROTATE_LEFT((a), (s)); \
    142.  (a) += (b); \
    143.   }
    144.  
    145.  
    146. /* MD5 basic transformation. Transforms state based on block. */
    147.  
    148. static void MD5Transform(UINT4 state[4], const unsigned char block[64])
    149. {
    150.   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    151.   /* Move contents of block to x, putting bytes in little-endian order. */
    152.   #ifdef LITTLE_ENDIAN
    153.     memcpy(x, block, 64);
    154.   #else
    155.   {
    156.     unsigned int i, j;
    157.     for (i = j = 0; i < 16; i++, j+= 4)
    158.     {
    159.       x[i] = (UINT4) block[j] | (UINT4) block[j+1] << 8 |
    160.         (UINT4) block[j+2] << 16 | (UINT4) block[j+3] << 24;
    161.     }
    162.   }
    163.   #endif
    164.   /* Round 1 */
    165.   FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
    166.   FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
    167.   FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
    168.   FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
    169.   FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
    170.   FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
    171.   FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
    172.   FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
    173.   FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
    174.   FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
    175.   FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
    176.   FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
    177.   FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
    178.   FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
    179.   FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
    180.   FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
    181.   /* Round 2 */
    182.   GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
    183.   GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
    184.   GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
    185.   GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
    186.   GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
    187.   GG(d, a, b, c, x[10], S22,  0x2441453); /* 22 */
    188.   GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
    189.   GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
    190.   GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
    191.   GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
    192.   GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
    193.   GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
    194.   GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
    195.   GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
    196.   GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
    197.   GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
    198.   /* Round 3 */
    199.   HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
    200.   HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
    201.   HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
    202.   HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
    203.   HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
    204.   HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
    205.   HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
    206.   HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
    207.   HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
    208.   HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
    209.   HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
    210.   HH(b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
    211.   HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
    212.   HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
    213.   HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
    214.   HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
    215.   /* Round 4 */
    216.   II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
    217.   II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
    218.   II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
    219.   II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
    220.   II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
    221.   II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
    222.   II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
    223.   II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
    224.   II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
    225.   II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
    226.   II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
    227.   II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
    228.   II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
    229.   II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
    230.   II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
    231.   II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
    232.   state[0] += a;
    233.   state[1] += b;
    234.   state[2] += c;
    235.   state[3] += d;
    236.   /* Zeroize sensitive information. */
    237.   memset(x, 0, sizeof(x));
    238. }
    239.  
    240. void MD5Digest(MD5 *md5, const void *input, unsigned int inputLen)
    241. {
    242.   unsigned int i, index, partLen;
    243.   /* Compute number of bytes mod 64 */
    244.   index = (unsigned int)((md5->count[0] >> 3) & 0x3F);
    245.   /* Update number of bits */
    246.   if ((md5->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
    247.     md5->count[1]++;
    248.   md5->count[1] += ((UINT4)inputLen >> 29);
    249.   partLen = 64 - index;
    250.   /* Transform as many times as possible.*/
    251.   if (inputLen >= partLen)
    252.   {
    253.     memcpy(&md5->buffer[index], input, partLen);
    254.     MD5Transform(md5->state, md5->buffer);
    255.     for (i = partLen; i + 63 < inputLen; i += 64)
    256.       MD5Transform(md5->state, (const unsigned char *) input + i);
    257.     index = 0;
    258.   }
    259.   else
    260.     i = 0;
    261.   /* Buffer remaining input */
    262.   memcpy(&md5->buffer[index], (char *) input + i, inputLen-i);
    263. }
    264.  
    265. /* ENCODE packs a 32-bit unsigned integer into 4 bytes in little-endian
    266.    order.
    267. */
    268.  
    269. #ifdef LITTLE_ENDIAN
    270. #define ENCODE(p,n) *(UINT4 *)(p) = n
    271. #else
    272. //#define ENCODE(p,n) (p)[0]=n,(p)[1]=n>>8,(p)[2]=n>>16,(p)[3]=n>>24
    273. #endif
    274.  
    275. void MD5Close(MD5 *md5, unsigned char digest[16])
    276. {
    277.   unsigned char bits[8];
    278.   unsigned int index, padLen;
    279.   static unsigned char PADDING[64] =
    280.   {
    281.     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    282.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    283.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    284.   };
    285.   /* Save number of bits */
    286.   ENCODE(bits, md5->count[0]);
    287.   ENCODE(bits+4, md5->count[1]);
    288.   /* Pad out to 56 mod 64. */
    289.   index = (unsigned int)((md5->count[0] >> 3) & 0x3f);
    290.   padLen = (index < 56) ? (56 - index) : (120 - index);
    291.   MD5Digest(md5, PADDING, padLen);
    292.   /* Append length (before padding) */
    293.   MD5Digest(md5, bits, 8);
    294.   /* Store state in digest */
    295.   ENCODE(digest, md5->state[0]);
    296.   ENCODE(digest+4, md5->state[1]);
    297.   ENCODE(digest+8, md5->state[2]);
    298.   ENCODE(digest+12, md5->state[3]);
    299.   /* Zeroize sensitive information. */
    300.   memset(md5, 0, sizeof(MD5));
    301. }
    302.  
    303. void Cmd5_hashDlg::OnBnClickedButton1()
    304. {
    305.     MD5 *pmd5 = new MD5;
    306.     unsigned buflen; // number of bytes in block
    307.     unsigned char digest[16]; // digest
    308.     //
    309.     UpdateData();
    310.     buflen = InputStr.GetLength();
    311.     MD5Open(pmd5);
    312.     MD5Digest(pmd5, InputStr.GetBuffer(), buflen);
    313.     MD5Close(pmd5, digest);
    314.     if(pmd5) delete pmd5;
    315.     //
    316.     char tmp[5];
    317.     char buf[100];
    318.     RtlZeroMemory(tmp,5);
    319.     RtlZeroMemory(buf,100);
    320.     // Bytes to string
    321.     for(int i=0; i<16; i++)
    322.     {
    323.         _itoa_s(digest[i],tmp,4,10);
    324.         lstrcatA(buf,tmp);
    325.         lstrcatA(buf,",");
    326.     }
    327.     SetWindowTextA((GetDlgItem(IDC_EDIT2))->m_hWnd,(LPCSTR)buf);
    328.     UpdateData();
    329.     //Msg(InputStr);
    330. }
     
  5. verelex

    verelex New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2006
    Сообщения:
    90
    все, разобрался:
    Код (Text):
    1. UpdateData(); // текст из Edit1 в m_Str
    2.     DWORD dwBufferLen;
    3.     BYTE *pbBuffer = new BYTE[1024];
    4.     if(pbBuffer)
    5.     {
    6.         memset(pbBuffer,0,1024);
    7.         dwBufferLen = m_Str.GetLength();
    8.         WideCharToMultiByte(CP_ACP,0,(WCHAR*)m_Str.GetBuffer(),dwBufferLen,
    9.             (char*)pbBuffer,dwBufferLen,0,0);
    10.         //MessageBoxA(0,(char*)pbBuffer,"you enter:",0);