MD5ハッシュを計算する

CryptCreateHashを利用するとハッシュを計算できる。このAPIは利用できるOSに制限があるものもあるがMD5以外にもSHA-1やMD4、SHA-256、SHA-512など様々なハッシュ計算に対応している。

ここで作成した関数は簡単にするためメモリ上のデータを一括してハッシュ計算処理に回している。小さなデータであればこの関数で十分だ。しかしファイルハッシュを計算したいときなどにはこの関数は利用しない方がいい。ファイルハッシュ計算時はファイルを少しずつ読み出しCryptHashDataを何度も呼び出して計算するのがいい。

依存環境:ATL
#include "atlstr.h"

#include "wincrypt.h"

//
//	MD5ハッシュ計算(128ビット)
//
//対応:Windows 95 OSR2以降
//
bool	GetMD5Hash(const void* pData,DWORD dwLen,BYTE pcbHashData[16])
{
	bool		ret;
	HCRYPTPROV	hCryptProv;
	HCRYPTHASH	hHash;
	BYTE		pbHash[0x7f];
	DWORD		dwHashLen;

	::ZeroMemory(pcbHashData,16);
	if(pData == NULL || dwLen == 0)
		return	false;

	dwHashLen = 16;
	hHash = NULL;
	hCryptProv = NULL;
	ret = false;
	if(::CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
	{
		if(::CryptCreateHash(hCryptProv,CALG_MD5,0,0,&hHash))
		{
			if(::CryptHashData(hHash,(BYTE*)pData,dwLen,0))
			{
				if(::CryptGetHashParam(hHash,HP_HASHVAL,pbHash,&dwHashLen,0)) 
				{
					::memcpy_s(pcbHashData,dwHashLen,pbHash,dwHashLen);
					ret = true;
				}
			}
		}
	}

	if(hHash)
		::CryptDestroyHash(hHash);
	if(hCryptProv)
		::CryptReleaseContext(hCryptProv,0);

	if(ret == false)
		::ZeroMemory(pcbHashData,dwHashLen);

	return	ret;
}





void	Test(void)
{
	bool		ret;
	int			i;
	BYTE		pcbData[16];
	CAtlString	strTmp;
	CAtlString	strMessage;


	//"abc"という文字のMD5ハッシュを計算
	ret = GetMD5Hash("abc",3,pcbData);

	if(ret == false)
	{
		::MessageBox(NULL,_T("取得に失敗しました"),_T(""),MB_OK);
		return;
	}

	for(i = 0; i < 16; i++)
	{
		strTmp.Format(_T("%x"),pcbData[i]);
		strMessage += strTmp;
	}

	::MessageBox(NULL,strMessage,_T(""),MB_OK);
}

プロジェクトファイルをダウンロード


カテゴリー「システム情報」 のエントリー