Delphi HMAC-SHA1意外结果

时间:2014-03-11 22:42:45

标签: delphi rfc rfc-4226

我正在使用旧版本的Delphi(Delphi 5)编写,原因是我无法在此主题中解释。我正在尝试实现HOTP,目前我的所有代码都缺少HMACSHA1部分,我不明白为什么。我根据RFC 2202实现了HMACSHA,并将我的结果与众多其他HMACSHA1生成器进行了比较。所有这些都匹配。

然后我开始为HOTP实施RFC 4226,并且惊讶地发现我的中间HMACSHA1结果与它们在RFC底部提供的样本数据(https://www.ietf.org/rfc/rfc4226.txt)相比是错误的。

这是来自RFC的测试向量

  

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

     

秘密= 0x3132333435363738393031323334353637383930

     

表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

与链接到下面的在线生成器

相同

http://www.freeformatter.com/hmac-generator.html#ad-output

那么,我做错了什么?

1 个答案:

答案 0 :(得分:1)

至少有一个问题 - 您正在检查密钥> blocksize(64),但你还必须检查比块大小(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));

注意 - 使用Byte Arrays更好