2013-05-06 67 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