2

このスレッドで説明できない理由により、古いバージョンの 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

それで、私は何を間違っていますか?

4

1 に答える 1

1

少なくとも 1 つの問題 - キー > ブロックサイズ (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));

注 - バイト配列の方がはるかに優れています

于 2014-03-12T00:58:53.447 に答える