2013-05-06 81 views
0

Delphi Xe4。 使用功能Win CryptoAPI - CryptEncrypt & CryptDecrypt。CryptEncrypt獲取哈希數據

http://msdn.microsoft.com/en-us/library/windows/desktop/aa379924(v=vs.85).aspx(ENC) http://msdn.microsoft.com/en-us/library/windows/desktop/aa379913(v=vs.85).aspx(DECR)

一切正常,加密和解密的字符串。 但所有的例子,我看到選項「HCRYPTHASH hHash」沒有使用,是0. 我需要加密多個加密字符串發出其散列(不單獨計算,獲得與CryptEncrypt(hProv,哈希, ...)和解密。 - 源字符串的哈希得到

我不知道如何實現它

我將不勝感激,如果有人將顯示在德爾福的例子

刪除ps更新 *

回答

3

我想你試圖加密&散列純文本數據在一次傳遞? 如果是,那麼首先你必須創建一個Hash對象並將它的句柄傳遞給CryptEncrypt API。然後使用CryptGetHashParam檢索哈希。

這是一個僞代碼(未測試,但給你一個想法如何進行):

procedure doSomeEncryption() 
var 
    HASHOBJ: HCRYPTHASH; 
    hProv: HCRYPTPROV; 
    bHash: tBytes; 
    dwHashBytes: DWORD; 
begin 
    if not CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then 
    raiseLastOsError; 

    if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @HASHOBJ) then 
    raiseLastOsError; 

    // Your encrypt stuff here 
    CryptEncrypt(yourHKey, HASHOBJ, ...) // 

    setLength(bHash, 255); // Allocate the buffer 
    if CryptGetHashParam(HASHOBJ, HP_HASHVAL, @bHash[0], @dwHashBytes, 0) then 
    begin 
    setLength(bHash, dwHashBytes); // bHash now contains the hash bytes 
    end 
    else 
    setLength(bHash, 0); 

    // Release HASHOBJ 
    CryptDestroyHash(HASHOBJ); 

    // Release Provider Context 
    CryptReleaseContext(hProv, 0); 

end; 
  • 在我的僞碼我靠Jedi API project (JWA),因爲它包含了幾乎所有的Windows API的翻譯和類型(包括Crypt API)。你可以將它包含在你的項目中。
  • 僞代碼需要對API錯誤處理進行一些改進。
  • bHash包含數據的純文本版本的散列。 請注意散列(以及加密)是以字節爲導向的操作。這是它不「理解」字符串編碼。 用UTF16,UTF8和ASCII編碼的相同字符串值將具有不同的字節表示形式,因此它將具有不同的哈希值。記住哈希/加密時的編碼。

this behavior is documented for CryptEncrypt API in MSDN BTW:

hHash [in]一個句柄哈希對象。如果要對數據進行散列並同時加密,則可以在hHash參數 中傳遞散列對象的句柄。散列值隨傳入的明文 而更新。此選項在生成已簽名和加密的 文本時非常有用。在調用CryptEncrypt之前,應用程序必須通過調用CryptCreateHash函數獲取散列對象的 句柄。 加密完成後,可以使用CryptGetHashParam函數通過 獲得散列值,或者可以使用CryptSignHash函數使用 對散列進行簽名。如果不需要完成散列,則此 參數必須爲NULL。

UPDATE

後加密H1將是數據的加密前即H1 = HASH( 'AAA')

散列後解密H2將解密後的數據的散列(明文值)。

所以在你的情況下,如果解密成功,那麼H2將等於HASH('aaa'),即H1 = H2。

H1的目的& H2是檢查數據完整性。通常解密函數不會告訴你解密是否成功。如果您嘗試使用錯誤的密碼解密數據,則會收到垃圾字節。所以存在這個問題 - 如何知道解密是否成功?一種方法是在輸入和輸出上使用數據的散列。如果他們匹配 - 你的解密是成功的。如果哈希值不同,那麼由於密碼錯誤(例如),可能解密失敗了。 CryptEncrypt/CryptDecrypt提供了一種方便的方式來在一個操作中獲得這些散列,而不是單獨散列它。

+0

謝謝。是的,我談到了它。在此之前,我也想到了,但是我對字符串及其長度的翻譯感到困惑,所以如果可能的話,不要再僞代碼(需要正常):)並參見更新* – 2013-05-06 16:27:01

+0

對於真實代碼,請添加您的加密程序的問題。 – 2013-05-06 16:39:13

+0

查看更新2代碼 – 2013-05-06 16:53:13