Delphi HMAC-SHA1意外结果

Delphi HMAC-SHA1意外结果,delphi,rfc,rfc-4226,Delphi,Rfc,Rfc 4226,我正在用旧版本的Delphi(Delphi5)写作,原因是我无法在这篇文章中解释。我正在尝试实现一个HOTP,目前我所有的代码都缺少HMACSHA1部分,我不明白为什么。我根据RFC2202实现了HMACSHA,并将我的结果与许多其他HMACSHA1生成器进行了比较。所有这些都匹配 然后,我开始为HOTP实现rfc4226,并惊讶地发现,与RFC()底部提供的样本数据相比,我的中间HMACSHA1结果是错误的 这是来自RFC的测试向量 以下测试数据使用ASCII字符串 “123456789001

我正在用旧版本的Delphi(Delphi5)写作,原因是我无法在这篇文章中解释。我正在尝试实现一个HOTP,目前我所有的代码都缺少HMACSHA1部分,我不明白为什么。我根据RFC2202实现了HMACSHA,并将我的结果与许多其他HMACSHA1生成器进行了比较。所有这些都匹配

然后,我开始为HOTP实现rfc4226,并惊讶地发现,与RFC()底部提供的样本数据相比,我的中间HMACSHA1结果是错误的

这是来自RFC的测试向量

以下测试数据使用ASCII字符串 “123456789001234567890”的秘密:

机密=0x31323334353637393933031323334353637383939330

表1各计数的详细信息,中间HMAC值

计数十六进制HMAC-SHA-1(机密,计数)

0 cc93cf18508d94934c64b65d8ba7667fb7cde4b0

但是,使用我的HMACSHA1函数,如下所示:

function HMAC_SHA1(Text, Key: AnsiString): AnsiString;
var
  ipad, opad, s: AnsiString;
  n: Integer;
  SHA1Context: TSHA1Ctx;
begin
  if Length(Key) > 64 then
    Key := SHA1(Key);
  ipad := StringOfChar(#$36, 64);
  opad := StringOfChar(#$5C, 64);
  for n := 1 to Length(Key) do
  begin
    ipad[n] := AnsiChar(Byte(ipad[n]) xor Byte(Key[n]));
    opad[n] := AnsiChar(Byte(opad[n]) xor Byte(Key[n]));
  end;
  SHA1Init(SHA1Context);
  SHA1Update(SHA1Context, ipad);
  SHA1Update(SHA1Context, Text);
  s := SHA1Final(SHA1Context);
  SHA1Init(SHA1Context);
  SHA1Update(SHA1Context, opad);
  SHA1Update(SHA1Context, s);
  Result := SHA1Final(SHA1Context);
end;
我试图:

HMAC_SHA1('12345678901234567890', '0');
我的回答是

948d4b44f3e0aac05904d6fd82ab7b8bbe761a4c

与下面链接的联机生成器相同


那么,我做错了什么呢?

至少有一个问题-您正在检查keys>blocksize(64),但您还必须检查短于blocksize(64)的键,这些键需要用零正确填充

上面的代码中有类似的内容

//current check if > length
if Length(Key) > 64 then
    Key := SHA1(Key);

//also check < length
if Length(Key) < 64 then
   Key := Key + StringOfChar(#0, 64 - Length(Key));
//当前检查是否>长度
如果长度(键)>64,则
键:=SHA1(键);
//同时检查<长度
如果长度(键)<64,则
Key:=Key+StringOfChar(#0,64-长度(Key));

注意-使用字节数组更好

链接到的纸张使用的是计数,而不是键。请尝试传入0,而不是“0”。这不是问题所在,但您需要的是字节数组而不是字符串