Delphi - Не удается заставить HMAC-SHA256 пройти тестовые векторы RFC 4231

Мне нужно получить доступ к службам Amazon REST, как и в предыдущем вопросе по адресу «HMAC-SHA256 в Дельфы" спросил. Поскольку это должно быть в D2010, я пытаюсь использовать последнюю версию libeay32.dll для прохождения тестовых векторов в RFC 4231:

http://tools.ietf.org/html/rfc4231

У кого-нибудь есть метод, который проходит эти тесты в Delphi, используя эту библиотеку? Код, размещенный shunty в посте, на который я ссылался, проходит первые два тестовых вектора, а также пятый, но терпит неудачу в третьем и четвертом.Эти векторы имеют размер более 64 байт, и, поскольку все URL-адреса, которые мне нужно подписать для Amazon, имеют размер более 64 байт, это проблема. Я не смог понять, делаю ли я что-то не так. Тест OpenSSL есть в hmactest.c, но он проверяет только EVP_md5, а тестовые векторы не такие, как в RFC. Мне это нужно для работы с SHA256, чтобы я мог проверить тестовые векторы в RFC. Я использую следующие константы для тестов (константы теперь обновлены для будущих зрителей, чтобы исправить мои ошибки копирования и вставки, упомянутые в комментариях ниже):

const
  LIBEAY_DLL_NAME = 'libeay32.dll';
  EVP_MAX_MD_SIZE = 64;

  //RFC 4231 Test case 1
  TEST1_KEY: string = '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b';
  TEST1_DATA: string = '4869205468657265';
  TEST1_DIGEST: string = 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7';

  //RFC 4231 Test case 2
  TEST2_KEY = '4a656665';
  TEST2_DATA = '7768617420646f2079612077616e7420666f72206e6f7468696e673f';
  TEST2_DIGEST = '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843';

  //RFC 4231 Test case 3
  TEST3_KEY = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
  TEST3_DATA = 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd';
  TEST3_DIGEST = '773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe';

  //RFC 4231 Test case 4
  TEST4_KEY = '0102030405060708090a0b0c0d0e0f10111213141516171819';
  TEST4_DATA = 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd';
  TEST4_DIGEST = '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b';

  //RFC 4231 Test case 5
  TEST5_KEY = '0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c';
  TEST5_DATA = '546573742057697468205472756e636174696f6e';
  TEST5_DIGEST = 'a3b6167473100ee06e0c796c2955552b';

Я не знаю, как этот код от shunty будет выглядеть вставленным, потому что он здесь выглядит ужасно (я новичок в stackoverflow). Я использовал RAND_seed, а не RAND_load_file, как он, но в остальном это то же самое:

function TForm1.GetHMAC(const AKey, AData: string): TBytes;
var
  key, data: TBytes;
  md_len: integer;
  res: PByte;
  buf: PInteger;
  rand_val: Integer;
begin
  OpenSSL_add_all_algorithms;

  Randomize;
  rand_val := Random(100);
  GetMem(buf, rand_val);
  try
    RAND_seed(buf, rand_val);

    key := TEncoding.UTF8.GetBytes(AKey);
    data := TEncoding.UTF8.GetBytes(AData);
    md_len := EVP_MAX_MD_SIZE;
    SetLength(Result, md_len);
    res := HMAC(EVP_sha256, @key[0], Length(key), @data[0], Length(data), @result[0], md_len);
    if (res <> nil) then
      SetLength(Result, md_len);

  finally
    FreeMem(buf);
  end;
end;

Код, который я использую для тестирования, выглядит следующим образом. Этот конкретный метод предназначен для теста 3, который терпит неудачу. Результатом будет bb861233f283aef2ef7aea09785245c9f3c62720c9d04e0c232789f27a586e44, но он должен быть равен постоянному шестнадцатеричному значению для TEST3_DIGEST:

procedure TForm1.btnTestCase3Click(Sender: TObject);
var
  LBytesDigest: TBytes;
  LHashString: string;
  LHexDigest: string;
begin
  LBytesDigest := GetHMAC(HexToStr(TEST3_KEY), HexToStr(TEST3_DATA));

  LHexDigest := LowerCase(BytesToHex(LBytesDigest));

  if LHexDigest = TEST3_DIGEST then begin
    Memo1.Lines.Add('SUCCESS: Matches test case');
    Memo1.Lines.Add(LHexDigest);
  end else begin
    Memo1.Lines.Add('ERROR: Does not match test case');
    Memo1.Lines.Add('Result:    ' + LHexDigest);
    Memo1.Lines.Add('Test Case: ' + TEST3_DIGEST);
  end;
end;

Есть идеи? Я собираюсь сдаться и просто создать приложение .NET, используя предоставленную ими библиотеку...

5
задан Community 23 May 2017 в 12:20
поделиться