【发布时间】:2010-02-09 10:46:09
【问题描述】:
我正在尝试使用 Microsoft 'Crypt...' 函数从添加到散列对象的数据中生成 MD5 散列密钥。我还尝试使用“CryptSetHashParam”将哈希对象设置为特定的哈希值,然后再向其中添加数据。
根据 Microsoft 文档(如果我的解释正确),您应该能够通过创建原始对象的重复哈希来做到这一点,使用“CryptGetHashParam”函数检索哈希大小,然后使用“CryptSetHashParam”在原始对象上相应地设置哈希值。我知道在使用 'CryptGetHashParam' 后,您无法将其他数据添加到哈希对象(这就是我认为您需要创建副本的原因),但我无法将数据添加到原始哈希对象或副本使用“CryptGetHashParam”(如预期)或“CryptSetHashParam”(我没想到)后的哈希对象。
以下是我正在编写的类的代码摘录以及我如何使用类函数的示例:
我运行代码后得到的结果是:
“AddDataToHash 函数失败 - 错误代码:2148073484。”,翻译为:“哈希在指定状态下无效。”。
我尝试了许多不同的方法来尝试使其按预期工作,但结果始终相同。我承认我做错了什么,但我看不出我做错了什么。请问有什么想法吗?
类构造函数初始化。
CAuthentication::CAuthentication()
{
m_dwLastError = ERROR_SUCCESS;
m_hCryptProv = NULL;
m_hHash = NULL;
m_hDuplicateHash = NULL;
if(!CryptAcquireContext(&m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
{
m_dwLastError = GetLastError();
if (m_dwLastError == 0x80090016 )
{
if(!CryptAcquireContext(&m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
{
m_dwLastError = GetLastError();
m_hCryptProv = NULL;
}
}
}
if(!CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash))
{
m_dwLastError = GetLastError();
m_hHash = NULL;
}
}
用于设置散列对象的散列值的函数。
bool CAuthentication::SetHashKeyString(char* pszKeyBuffer)
{
bool bHashStringSet = false;
DWORD dwHashSize = 0;
DWORD dwHashLen = sizeof(DWORD);
BYTE byHash[DIGITAL_SIGNATURE_LENGTH / 2]={0};
if(pszKeyBuffer != NULL && strlen(pszKeyBuffer) == DIGITAL_SIGNATURE_LENGTH)
{
if(CryptDuplicateHash(m_hHash, NULL, 0, &m_hDuplicateHash))
{
if(CryptGetHashParam(m_hDuplicateHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&dwHashSize), &dwHashLen, 0))
{
if (dwHashSize == DIGITAL_SIGNATURE_LENGTH / 2)
{
char*pPtr = pszKeyBuffer;
ULONG ulTempVal = 0;
for(ULONG ulIdx = 0; ulIdx < dwHashSize; ulIdx++)
{
sscanf(pPtr, "%02X", &ulTempVal);
byHash[ulIdx] = static_cast<BYTE>(ulTempVal);
pPtr+= 2;
}
if(CryptSetHashParam(m_hHash, HP_HASHVAL, &byHash[0], 0))
{
bHashStringSet = true;
}
else
{
pszKeyBuffer = "";
m_dwLastError = GetLastError();
}
}
}
else
{
m_dwLastError = GetLastError();
}
}
else
{
m_dwLastError = GetLastError();
}
}
if(m_hDuplicateHash != NULL)
{
CryptDestroyHash(m_hDuplicateHash);
}
return bHashStringSet;
}
用于添加散列数据的函数。
bool CAuthentication::AddDataToHash(BYTE* pbyHashBuffer, ULONG ulLength)
{
bool bHashDataAdded = false;
if(CryptHashData(m_hHash, pbyHashBuffer, ulLength, 0))
{
bHashDataAdded = true;
}
else
{
m_dwLastError = GetLastError();
}
return bHashDataAdded;
}
主函数类用法:
CAuthentication auth;
.....
auth.SetHashKeyString("0DD72A4F2B5FD48EF70B775BEDBCA14C");
.....
if(!auth.AddDataToHash(pbyHashBuffer, ulDataLen))
{
TRACE("CryptHashData function failed - Errorcode: %lu.\n", auth.GetAuthError());
}
【问题讨论】:
标签: c++ cryptography md5 hash