「 DelphiのHMAC-SHA256」での前の質問のように、AmazonRESTサービスにアクセスする必要があります。これはD2010にある必要があるため、RFC4231のテストベクトルに合格するために最新のlibeay32.dllを使用しようとしています。
https://www.rfc-editor.org/rfc/rfc4231
このライブラリを使用してDelphiでこれらのテストに合格するメソッドを持っている人はいますか?私が参照した投稿でshuntyによって投稿されたコードは、最初の2つのテストベクトルと5番目のテストベクトルに合格しますが、3番目と4番目では失敗します。これらのベクターは64バイトを超えており、Amazonに署名する必要のあるURLはすべて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_load_fileではなくRAND_seedを使用しましたが、それ以外は同じです。
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の定数の16進値と同じである必要があります。
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アプリを作成しようとしています...