使用CryptoAPI计算HASH和HMAC

记录一下hash和hmac的算法.

static void Hash(ALG_ID algId, BYTE* pData, DWORD dataLength, BYTE* pCode,DWORD* pdwLength)
{
	HCRYPTPROV hProv = NULL;
	BOOL blRet = FALSE;
	blRet=CryptAcquireContext(&hProv,
		NULL, NULL,
		PROV_RSA_FULL, 0);

	HCRYPTHASH hHash = NULL;
	blRet=CryptCreateHash(hProv,
		algId,		0, 0,		& hHash);

	blRet = CryptHashData(hHash, pData, dataLength, 0);

	DWORD dwLen = 20;
	blRet = CryptGetHashParam(hHash, HP_HASHVAL,NULL, &dwLen, 0);

	blRet=CryptGetHashParam(hHash, HP_HASHVAL, pCode, &dwLen, 0);

	CryptDestroyKey(hHash);
	CryptReleaseContext(hProv,0);
	*pdwLength = dwLen;
}

static void MyHMAC(ALG_ID algId, BYTE* _pKey, DWORD _dwKeyLength, BYTE* pData,DWORD dwDataLength,
	BYTE* pHMAC, DWORD* pdwHMACLength)
{
	const DWORD B = 64;		//MD5和SHA这个值是64

	//首先第一步: 如果Key不足B长度,尾部填充0至B长度。
				//如果key长度大于B,则先将key进行HASH,然后结果如果小于B,尾部填充至B长度。
	BYTE fillKey[200]; DWORD dwFillKey = 0;
	if (_dwKeyLength > 64)
	{
		Hash(algId, _pKey, _dwKeyLength, fillKey, &dwFillKey);
	}
	else
	{
		dwFillKey = _dwKeyLength;
		memcpy(fillKey, _pKey, _dwKeyLength);
	}

	for (int i = dwFillKey; i < B; i++)
		fillKey[i] = 0;
	/
	//第二步,填充ipad和opad。 都是B长度。
	//拷贝FillKey到ipad和opad,然后进行异或运算
	BYTE k_ipad[B], k_opad[B];
	memcpy(k_ipad, fillKey, B);
	memcpy(k_opad, fillKey, B);
	for (int i = 0; i < B; i++)
	{
		k_ipad[i]^= 0x36;
		k_opad[i] ^= 0x5c;
	}

	//将ipad与data连接起来进行hash
	DWORD dwConLength1 = B + dwDataLength;
	BYTE* pCon1 = new BYTE[dwConLength1];
	memcpy(pCon1, k_ipad, B);
	memcpy(pCon1 + B, pData, dwDataLength);

	BYTE HashSha1[200]; DWORD dwHashLen1 = 0;
	Hash(algId, pCon1, dwConLength1, HashSha1, &dwHashLen1);

	/

	//hash的长度,应该是固定的
	int HashLength = dwHashLen1;
	
	//将opad与上次hash的结果连接起来,进行hash ,结果就是hmac
	DWORD dwConLength2 = B + HashLength;
	BYTE* pCon2 = new BYTE[dwConLength2];
	memcpy(pCon2, k_opad, B);
	memcpy(pCon2 + B, HashSha1, HashLength);

	BYTE HashSha2[200]; DWORD dwHashLen2 = 0;
	Hash(algId, pCon2, dwConLength2, HashSha2, &dwHashLen2);

	memcpy(pHMAC, HashSha2, HashLength);
	*pdwHMACLength = dwHashLen2;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值