我正在嘗試使用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