Я пишу в старой версии Delphi (Delphi 5) по причинам, которые не могу объяснить в этой теме. Я пытаюсь реализовать HOTP, и в настоящее время весь мой код работает без части HMACSHA1, и я не понимаю, почему. Я реализовал HMACSHA в соответствии с RFC 2202 и сравнил свои результаты с многочисленными другими генераторами HMACSHA1. Все это совпало.
Затем я начал реализовывать RFC 4226 для HOTP и был удивлен, увидев, что мои промежуточные результаты 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
Итак, что я делаю неправильно?