"HMAC-SHA256 in Delphi" adlı bir önceki soru gibi Amazon REST hizmetlerine erişmem gerekiyor. Bu ben RFC 4231 test vektörleri geçmek son libeay32.dll kullanmaya çalışıyorum D2010 olmak zorunda beri:Delphi - HMAC-SHA256'nın RFC 4231 test vektörlerini geçmesine izin verilmiyor
http://tools.ietf.org/html/rfc4231
herkes bu kütüphaneyi kullanan Delphi bu testleri geçecek bir yöntem var mı ? Gönderdiğim yazıdaki şantiyenin gönderdiği kod, ilk iki test vektörünü ve beşinciyi geçiyor, ancak üçüncü ve dördüncü sırada başarısız oluyor. Bu vektörler 64 bayttan fazladır ve Amazon için imzalamam gereken tüm URL'ler 64 bayttan fazla olduğundan bu bir problemdir. Yanlış bir şey yapıp yapmadığımı anlayamadım. OpenSSL testi hmactest.c dosyasındadır, ancak yalnızca EVP_md5'i kontrol eder ve test vektörleri RFC'deki ile aynı değildir. SHA256 ile çalışmak için buna ihtiyacım var, bu yüzden RFC'deki test vektörlerine karşı doğrulayabilirim. Ben (aşağıda yorum olarak bahsedilen benim kopyalama ve yapıştırma hataları düzeltmek için şimdi gelecekteki izleyiciler için güncellenmiş sabitler) testleri için aşağıdaki sabitleri kullanıyorum:
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';
Ben shunty bu kod nasıl görüneceğini bilmiyorum yapıştırılmış çünkü burada korkunç görünüyor (Ben bir stackoverflow acemi değilim). Daha doğrusu onun gibi RAND_load_file daha RAND_seed kullanılır, ancak aksi takdirde aynı: Ben testine kullanmak
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;
kod buna benzemez. Bu özel yöntem, başarısız olan test 3 içindir. Sonuç bb861233f283aef2ef7aea09785245c9f3c62720c9d04e0c232789f27a586e44, ancak TEST3_DIGEST için sabit onaltılık değerine eşit olmalıdır:
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;
Herhangi bir fikir? Vazgeçmek üzereyim ve sağladıkları kütüphaneyi kullanarak bir .NET uygulaması yaratıyorum ...
Benim savunmamda, UTF8.GetBytes kullanıldı çünkü bu, üzerinde çalıştığımız özel uygulamanın içeriğinin ne olduğuydu - hiçbir zaman uygulama dışında hiçbir şeyle etkileşim kurmuyorduk. Ve gönderinin altında referans verilere karşı kullanmadığımı belirten bir yasal uyarı var. Ve son iki yılda geliştirdik :-) – shunty
İlginç. Bir noktada, TBytes'i parametre olarak kullanan aşırı yüklenmiş bir GetHMAC vardı. Yine de, RFC'den Hex kodlanmış testlerini kullanıp kullanmadığımı bilmiyorum. Muhtemelen bazı Unicode sorunları nedeniyle işe yaramadı. Daha önce hiç böyle bir şeyle uğraşmak zorunda kalmamıştım. Amazon için bir URI almalısınız, HMAC SHA1 veya SHA256 ile dönüştürmeli, sonra bunu Base64'e dönüştürmeli, daha sonra URL bunu kodlayacak, ardından imzayı orijinal URI'ye ekleyecektir. Delphi'de bir köpekbalığı tankından diğerine ve tekrar diğerine yürümek gibi. Amazon'un .NET kütüphanesinin kullandığı kod, karşılaştırma yaparak çok basit. –
@shunty - Orijinal gönderi için teşekkürler.Yorumda, düzenlemenin herhangi bir noktasında düşmüş herhangi bir referans verisine karşı test etmediğinizi söylediniz. Bu iyiydi çünkü feragatnameniz, RFC'yi bulmamı sağladı ve onaltılık kodlanmış testlerini işe almaya çalıştı. –