我正在尝试使用Microsoft'Crypt ...'函数从添加到哈希对象的数据生成MD5哈希键。我还试图在向其添加数据之前使用'CryptSetHashParam'将哈希对象设置为特定的哈希值。为什么在使用'CryptSetHashParam'之后,我不能再向我的MD5哈希对象添加数据?
根据Microsoft文档(如果我正确解释它),您应该可以通过创建原始对象的重复哈希来执行此操作,使用'CryptGetHashParam'函数检索哈希大小,然后使用'CryptSetHashParam '在原始对象上相应地设置散列值。我知道在使用'CryptGetHashParam'之后,你无法向散列对象添加额外的数据(这就是为什么我认为你需要创建一个副本),但我不能将数据添加到原始散列对象或重复使用'CryptGetHashParam'(如预期)或'CryptSetHashParam'(我没有想到)之后的哈希对象。
下面是我写的类代码提取和我如何使用类函数的例子:
结果运行代码后,我得到的是:
“AddDataToHash功能失败 - 错误代码:2148073484.“,它转换为:”哈希无效在指定状态下使用。“。
我试过很多不同的方法来试图按预期工作,但结果总是一样的。我接受我做错了什么,但我不明白我做错了什么。请有任何想法吗?
CLASS CONSTRUCTOR INITIALISATION。
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;
}
功能用于添加数据进行Hashing。
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());
}
我想我应该解释为什么我要用预定义的开始散列值来初始化散列对象,以突出显示我想要克服的问题。数据我哈希来自一个包含数百个文件的NAS。在对每个文件中的数据进行散列处理之后,我希望在本地保留MD5散列,以便如果哈希应用程序遭受中断并重新启动,则会在中断点处使用散列值初始化新的散列对象,从而防止需要再次从NAS开始哈希。有没有办法做到这一点? – 2010-02-11 09:20:22
如果没有更多的文件被添加到NAS中,并且MD5哈希对所有文件中包含的所有数据都没有中断地执行,那么如果所有数据再次被散列,结果散列值不会不同,但是这次中断遇到。如果我正确地解释了之前所说的内容,则表明在中断之前计算的散列值在下一个文件数据之前被送入散列对象。这不会导致散列数据被计算在散列数据上,从而导致不同的最终散列值与不间断散列值的散列值不同? – 2010-02-12 10:46:44
您跟踪上次成功散列文件。当散列文件i + 1中间发生中断时,您只需丢弃部分结果并重新开始,重新计算MD5(H_i || file_ {i + 1})= H_ {i + 1}。 – 2010-02-13 00:51:33