VC 使用CryptoAPI计算Hash值:MD5, SHA

#include "stdafx.h"
#define _WIN32_WINNT 0x0400
#include 
<tchar.h>
#include 
<wincrypt.h>

// 计算Hash,成功返回0,失败返回GetLastError()
//  CONST BYTE *pbData, // 输入数据 
//  DWORD dwDataLen,     // 输入数据字节长度 
//  ALG_ID algId              // Hash 算法:CALG_MD5,CALG_SHA
//  LPTSTR pszHash,        // 输出16进制Hash字符串,MD5长度为32+1, SHA长度为40+1
// 
DWORD GetHash(CONST BYTE *pbData, DWORD dwDataLen, ALG_ID algId, LPTSTR pszHash)
{
  DWORD dwReturn 
= 0;
  HCRYPTPROV hProv;
  
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
    
return (dwReturn = GetLastError());

  HCRYPTHASH hHash;
  
//Alg Id:CALG_MD5,CALG_SHA
  if(!CryptCreateHash(hProv, algId, 00&hHash)) 
  {
    dwReturn 
= GetLastError();
    CryptReleaseContext(hProv, 
0);
    
return dwReturn;
  }

  
if(!CryptHashData(hHash, pbData, dwDataLen, 0))
  {
    dwReturn 
= GetLastError();
    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 
0);
    
return dwReturn;
  }
  
  DWORD dwSize;
  DWORD dwLen 
= sizeof(dwSize);
  CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE
*)(&dwSize), &dwLen, 0);

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

  lstrcpy(pszHash, _T(
""));
  TCHAR szTemp[
3];
  
for (DWORD i = 0; i < dwLen; ++i)
  {
    
//wsprintf(szTemp, _T("%X%X"), pHash[i] >> 4, pHash[i] & 0xf);
    wsprintf(szTemp, "%02X", pHash[i]);
    lstrcat(pszHash, szTemp);
  }
  delete [] pHash;

  CryptDestroyHash(hHash);
  CryptReleaseContext(hProv, 
0);
  
return dwReturn;
}

//=======================================================
// Test
int HashTest()
{
  TCHAR szStr[
20= {0};
  TCHAR szHash[
41= {0};

  strcpy(szStr,
"测试MD5");
  GetHash((BYTE
*)szStr, strlen(szStr), CALG_MD5,szHash);
  MessageBox(NULL, szHash, szStr, MB_OK);

  strcpy(szStr,
"测试SHA");
  GetHash((BYTE
*)szStr, strlen(szStr),CALG_SHA,szHash);
  MessageBox(NULL, szHash, szStr, MB_OK);
  
return 0
}

posted on 2008-12-31 12:34  大豆男生  阅读(3322)  评论(0编辑  收藏  举报

导航