点击(此处)折叠或打开

  1. // GetMd5Hash()
  2. // #include <wincrypt.h>
  3. // 功能:用MD5计算Hash
  4. // 参数:CONST BYTE *pbData, // 输入数据
  5. // DWORD dwDataLen, // 输入数据字节长度
  6. // LPTSTR pszHash, // 输出16进制Hash字符串,长度为32+1
  7. // 返回:成功返回TRUE, 失败返回FALSE, err内容为GetLastError()的值
  8. BOOL GetMd5Hash(CONST BYTE *pbData, DWORD dwDataLen, CString &strHash, DWORD &err)
  9. {
  10.     HCRYPTPROV hProv;
  11.     if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  12.     {
  13.         err = GetLastError();
  14.         return FALSE;
  15.     }

  16.     HCRYPTHASH hHash;
  17.     if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
  18.     {
  19.         err = GetLastError();
  20.         CryptReleaseContext(hProv, 0);
  21.         return FALSE;
  22.     }

  23.     if(!CryptHashData(hHash, pbData, dwDataLen, 0))
  24.     {
  25.         err = GetLastError();
  26.         CryptDestroyHash(hHash);
  27.         CryptReleaseContext(hProv, 0);
  28.         return FALSE;
  29.     }

  30.     DWORD dwSize;
  31.     DWORD dwLen = sizeof(dwSize);
  32.     CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)(&dwSize), &dwLen, 0);

  33.     BYTE* pHash = new BYTE[dwSize];
  34.     dwLen = dwSize;
  35.     CryptGetHashParam(hHash, HP_HASHVAL, pHash, &dwLen, 0);

  36.     strHash = _T("");
  37.     for(DWORD i=0; i<dwLen; i++)
  38.         strHash.AppendFormat(_T("%02X"), pHash[i]);
  39.     delete [] pHash;

  40.     CryptDestroyHash(hHash);
  41.     CryptReleaseContext(hProv, 0);
  42.     
  43.     return TRUE;
  44. }
调用方法,以计算字符串的MD5 HASH为例:
  1. CString authCodeHash;
  2. DWORD getHashErr = 0;
  3. BOOL getHashResult = GetMd5Hash((BYTE *)mAuthCode.GetString(), mAuthCode.GetLength() * sizeof(TCHAR), authCodeHash, getHashErr);
代码中mAuthCode是需要计算HASH的字符串变量,authCodeHash是计算结果。
注意字符串UNICODE编码和非UNICODE
编码计算结果是不一样的。

参考:
VC 使用CryptoAPI计算Hash值:MD5, SHA
11-08 07:42