gpt4 book ai didi

delphi - CryptoAPI 返回 HMAC_SHA1 的错误结果

转载 作者:行者123 更新时间:2023-12-03 15:54:30 28 4
gpt4 key购买 nike

我将下面的代码与 Crypto API 一起使用,但根据其他 API 和库的测试,我没有得到预期的结果。

我使用的是 key “key”,数据是“message

例如,使用 Indy 的 TidHMACSHA1,我得到 2088df74d5f2146b48146caf4965377e9d0be3a4

我使用在线生成器得到相同的结果(例如 http://www.freeformatter.com/hmac-generator.html )。

使用我编写的代码(见下文),我得到 4a52c3c0abc0a06049d1ab648bb4057e3ff5f359

代码如下,我使用的是 JEDI wcrypt2.pas header

function Hashhmacsha1(const Key, Value: AnsiString): AnsiString;
var
hCryptProvider: HCRYPTPROV;
hHash: HCRYPTHASH;
hKey: HCRYPTKEY;
bHash: array[0..$7F] of Byte;
dwHashLen: dWord;
i: Integer;


hHmacHash: HCRYPTHASH;
bHmacHash: array[0..$7F] of Byte;
dwHmacHashLen: dWord;
hmac_info : Wcrypt2.HMAC_INFO;
begin
dwHashLen := 32;
dwHmacHashLen := 32;
{get context for crypt default provider}
if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT or CRYPT_MACHINE_KEYSET) then
begin
{create hash-object }
if CryptCreateHash(hCryptProvider, CALG_SHA1, 0, 0, @hHash) then
begin

{get hash from password}
if CryptHashData(hHash, @Key[1], Length(Key), 0) then
begin

// hHash is now a hash of the provided key, (SHA1)
// Now we derive a key for it
if CryptDeriveKey(hCryptProvider, CALG_RC4, hHash, 0, @hKey) then
begin

//hkey now holds our key. So we have do the whole thing over again
//ZeroMemory( hmac_info, SizeOf(hmac_info) );
hmac_info.HashAlgid := CALG_SHA1;
if CryptCreateHash(hCryptProvider, CALG_HMAC, hKey, 0, @hHmacHash) then
begin

{get hash from password}

if CryptSetHashParam( hHmacHash, HP_HMAC_INFO, @hmac_info, 0) then
begin

if CryptHashData(hHmacHash, @Value[1], Length(Value), 0) then
begin
if CryptGetHashParam(hHmacHash, HP_HASHVAL, @bHmacHash[0], @dwHmacHashLen, 0) then
begin
for i := 0 to dwHmacHashLen-1 do
Result := Result + IntToHex(bHmacHash[i], 2);
end
else
WriteLn( 'CryptGetHashParam ERROR --> ' + SysErrorMessage(GetLastError)) ;
end
else
WriteLn( 'CryptHashData ERROR --> ' + SysErrorMessage(GetLastError)) ;
{destroy hash-object}
CryptDestroyHash(hHmacHash);
CryptDestroyKey(hKey);
end
else
WriteLn( 'CryptSetHashParam ERROR --> ' + SysErrorMessage(GetLastError)) ;

end
else
WriteLn( 'CryptCreateHash ERROR --> ' + SysErrorMessage(GetLastError)) ;
end
else
WriteLn( 'CryptDeriveKey ERROR --> ' + SysErrorMessage(GetLastError)) ;

end;
{destroy hash-object}
CryptDestroyHash(hHash);
end;
{release the context for crypt default provider}
CryptReleaseContext(hCryptProvider, 0);
end;
Result := AnsiLowerCase(Result);
end;

我显然做错了什么,但我不知道是什么??

最佳答案

所以我找到了一个解决方案,当使用 key “key”为数据“消息”生成 HMAC_SHA1 时,会生成预期的哈希值 2088df74d5f2146b48146caf4965377e9d0be3a4

如您所见,此代码使用 CryptImportKey 而不是 CryptDeriveKey,这似乎解决了该问题。看来使用 CryptDeriveKey 实际上是使用数据“消息”和编码为 RC4 的 key “key”的 SHA1 哈希来生成 HMAC_SHA1 哈希,而不是最初认为的明文 key 。

该代码适用于长度最多为 16 个字符的键(任何更大的字符),并且仅使用前 16 个字符。我正在发布第二个问题来询问这个问题!!

代码发布在下面。

function Hashhmacsha1(const Key, Value: AnsiString): AnsiString;
const
KEY_LEN_MAX = 16;
var
hCryptProvider: HCRYPTPROV;
hHash: HCRYPTHASH;
hKey: HCRYPTKEY;
bHash: array[0..$7F] of Byte;
dwHashLen: dWord;
i: Integer;

hPubKey : HCRYPTKey;
hHmacHash: HCRYPTHASH;
bHmacHash: array[0..$7F] of Byte;
dwHmacHashLen: dWord;
hmac_info : Wcrypt2.HMAC_INFO;

keyBlob: record
keyHeader: BLOBHEADER;
keySize: DWORD;
keyData: array[0..KEY_LEN_MAX-1] of Byte;
end;
keyLen : INTEGER;
begin
dwHashLen := 32;
dwHmacHashLen := 32;
{get context for crypt default provider}
if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then
begin
{create hash-object MD5}
if CryptCreateHash(hCryptProvider, CALG_SHA1, 0, 0, @hHash) then
begin

{get hash from password}
if CryptHashData(hHash, PByte(Key), Length(Key), 0) then
begin

// hHash is now a hash of the provided key, (SHA1)
// Now we derive a key for it
hPubKey := 0;

FillChar(keyBlob, SizeOf(keyBlob), 0);
keyBlob.keyHeader.bType := PLAINTEXTKEYBLOB;
keyBlob.keyHeader.bVersion := CUR_BLOB_VERSION;
keyBlob.keyHeader.aiKeyAlg := CALG_RC4;
KeyBlob.keySize := KEY_LEN_MAX;

if(Length(key) < (KEY_LEN_MAX))then
KeyLen := Length(key)
else
KeyLen := KEY_LEN_MAX;
Move(Key[1], KeyBlob.keyData[0], KeyLen );

if CryptImportKey(hCryptProvider, @keyBlob, SizeOf(KeyBlob), hPubKey, 0, @hKey) then
begin

//hkey now holds our key. So we have do the whole thing over again
ZeroMemory( @hmac_info, SizeOf(hmac_info) );
hmac_info.HashAlgid := CALG_SHA1;
if CryptCreateHash(hCryptProvider, CALG_HMAC, hKey, 0, @hHmacHash) then
begin
if CryptSetHashParam( hHmacHash, HP_HMAC_INFO, @hmac_info, 0) then
begin

if CryptHashData(hHmacHash, @Value[1], Length(Value), 0) then
begin
if CryptGetHashParam(hHmacHash, HP_HASHVAL, @bHmacHash[0], @dwHmacHashLen, 0) then
begin
for i := 0 to dwHmacHashLen-1 do
Result := Result + IntToHex(bHmacHash[i], 2);
end
else
WriteLn( 'CryptGetHashParam ERROR --> ' + SysErrorMessage(GetLastError)) ;
end
else
WriteLn( 'CryptHashData ERROR --> ' + SysErrorMessage(GetLastError)) ;
{destroy hash-object}
CryptDestroyHash(hHmacHash);
CryptDestroyKey(hKey);
end
else
WriteLn( 'CryptSetHashParam ERROR --> ' + SysErrorMessage(GetLastError)) ;

end
else
WriteLn( 'CryptCreateHash ERROR --> ' + SysErrorMessage(GetLastError)) ;
end
else
WriteLn( 'CryptDeriveKey ERROR --> ' + SysErrorMessage(GetLastError)) ;

end;
{destroy hash-object}
CryptDestroyHash(hHash);
end;
{release the context for crypt default provider}
CryptReleaseContext(hCryptProvider, 0);
end;
Result := AnsiLowerCase(Result);
end;

关于delphi - CryptoAPI 返回 HMAC_SHA1 的错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25436416/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com