![]() |
DXE7+Indy: HMAC SHA256 - Encoding
Hallo zusammen,
das eigentliche Kernproblem: Ich möchte die PHP-Funktionen hash_hmac und base64_encode in Delphi abbilden um das Datum '1234567890' mit dem Schlüssel 'ABCDEFG' zu signieren und das Ergebnis anschließend base64 kodieren. In PHP sieht das ganze folgendermaßen aus:
Code:
Ausgabe: aRGlc3RY1pKmKX0hvorkVKNcPigiJX2rksqXzlAeCLg=
echo base64_encode(hash_hmac('sha256', '1234567890', 'ABCDEFG', TRUE));
Ich habe die Indy-Klasse TIdHMACSHA256 auserkoren, dies für mich zu tun:
Delphi-Quellcode:
Rückgabewert: H3eBWh0jKF0WZIK+NcYdwXRQAWrMrNLfOM3/mBU0XpU=
uses
IdHash, IdHashSHA, IdHMACSHA1, IdSSLOpenSSL, IdGlobal, IdCoderMIME; function GenerateSignature(const AKey, AData: string): string; var AHMAC: TIdBytes; begin IdSSLOpenSSL.LoadOpenSSLLibrary; With TIdHMACSHA256.Create do try Key:= ToBytes(AKey, IndyTextEncoding_UTF16LE); AHMAC:= HashValue(ToBytes(AData, IndyTextEncoding_UTF16LE)); Result:= TIdEncoderMIME.EncodeBytes(AHMAC); finally Free; end; end; Auffällig ist, dass der Rückgabewert bei
Delphi-Quellcode:
nicht mit dem über PHP ermittelten Wert übereinstimmt.
Memo.Lines.Text:= GenerateSignature('1234567890', 'ABCDEFG');
Meine Kernfrage lautet also: Warum ist das so und wie bekomme ich den gleichen Wert, den ich über die PHP-Funktionen erhalte? Mein bisheriger Ansatz: Ich vermute ein Problem mit den Zeichensätzen. Ich habe verstanden, dass der Datentyp "string" bei Delphi XE7 dem Typ "UnicodeString" entspricht. UnicodeString arbeitet intern mit 2 Byte großen Zeichen (also 16bit) und ist UTF16 kodiert. ![]() Die Indy-Funktion "ToBytes" erwartet einen UnicodeString, sowie eine Zeichensatzangabe. Wird keine angegeben, wird ASCII verwendet, was ja zu Datenverlust führen könnte/wird. Also gebe ich UTF16 an. Da bei UTF16 zwischen BE (Big-Endian) und LE(Little-Endian) gewählt werden muss, habe ich mich für UTF16LE entschieden, da einerseits in einigen Artikeln im Netz LE als von "aktuellen Maschinen" verwendet bezeichnet wurde und andererseits Delphi's eigene Encodings "Unicode" und "BigEndianUnicode" heißen, was impliziert, dass Unicode (also LE) der Standard ist. Ich hatte hier auch bereits mit anderen Zeichensätzen experimentiert, jedoch ohne Erfolg. Da
Delphi-Quellcode:
bei Übergabe der IdBytes als Parameter zunächst alles in einen Stream schreibt und diesen dann mit Charset 8bit wieder ausliest, vermute ich hier ebenfalls eine Fehlerquelle. Daher habe ich stattdessen auch
TIdEncoderMIME.EncodeBytes(AHMAC);
Delphi-Quellcode:
probiert. Leider ebenfalls ohne Erfolg.
Result:= BytesToString(AHMAC, IndyTextEncoding_UTF16LE);
Result:= TIdEncoderMIME.EncodeString(Result, IndyTextEncoding_UTF16LE); Für jedwede Hilfe bin ich dankbar. Kai |
AW: DXE7+Indy: HMAC SHA256 - Encoding
Hallo,
hier die Lösung für alle, die ein ähnliches Problem haben:
Delphi-Quellcode:
Es muß also definitiv UTF8 verwendet werden, um ein gleiches Ergebnis zu erzielen.
function GenerateSignature(const AData, AKey: string): string;
var AHMAC: TIdBytes; begin IdSSLOpenSSL.LoadOpenSSLLibrary; IF NOT TIdHashSHA256.IsAvailable THEN Raise Exception.Create('SHA-256 hashing is not available!'); With TIdHMACSHA256.Create do try Key:= IndyTextEncoding_UTF8.GetBytes(AKey); AHMAC:= HashValue(IndyTextEncoding_UTF8.GetBytes(AData)); finally Free; end; Result:= TIdEncoderMIME.EncodeBytes(AHMAC); end; Für weitere Informationen zum Thema Amazon MWS Signatur mit Delphi und Indy, siehe auch den folgenden Thread in Englisch: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz