このスレッドで説明できない理由により、古いバージョンの Delphi (Delphi 5) で書いています。HOTP を実装しようとしていますが、現在、すべてのコードが HMACSHA1 の部分を除いて機能しており、その理由がわかりません。RFC 2202 に従って HMACSHA を実装し、その結果を他の多数の HMACSHA1 ジェネレーターと比較しました。これらはすべて一致しました。
次に、HOTP 用に RFC 4226 の実装を開始しましたが、RFC の下部にあるサンプル データ ( https://www.ietf.org/rfc/rfc4226.txt ) と比較して、HMACSHA1 の中間結果が間違っていることに驚きました。 )。
RFC のテスト ベクトルを次に示します。
次のテスト データでは、シークレットに ASCII 文字列 "12345678901234567890" が使用されます。
シークレット = 0x3132333435363738393031323334353637383930
表 1 は、各カウントの詳細、中間 HMAC 値です。
カウント 16 進数 HMAC-SHA-1(secret, count)
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
それで、私は何を間違っていますか?