AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

MD5 - Unterschiede zw. Indy und DEC6

Ein Thema von dschiffler · begonnen am 19. Mär 2024 · letzter Beitrag vom 23. Mär 2024
Antwort Antwort
Seite 1 von 3  1 23      
dschiffler

Registriert seit: 25. Okt 2006
30 Beiträge
 
Delphi 10.4 Sydney
 
#1

MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 11:37
Hallo,

ich verwende Indy zur Kommunikation mit einem Webserver.
Der Webserver verlangt Digest-Authentication und Indy hat dafür ja die Klasse TIdDigestAuthentication.
In dieser Klasse wird zur Berechnung des Hashes MD5 verwendet, was in der Klasse TIdHashMessageDigest5 implementiert ist.

Jetzt mal unabhängig davon, dass MD5 nicht mehr als sicher gilt, ist der Algorithmus als solcher ja standardisiert und
es sollte bei verschiedenen Komponenten, die Hash-Klassen anbieten, doch dann immer der gleiche Hash rauskommen, oder?

Jedenfalls benutze ich auch DEC6 und wenn ich mir da den MD5-Hash des gleichen Ausgangswertes mit der Klasse THash_MD5 geben lasse,
bekomme ich einen anderen Hash-Wert als bei Indy.
Delphi-Quellcode:
  lMD5_Indy := TIdHashMessageDigest5.Create;
  try
    sValue := lMD5_Indy.HashStringAsHex('Testwert');
  finally
    lMD5_Indy.Free;
  end;

  lMD5_DEC := THash_MD5.Create;
  try
    sValue := lMD5_DEC.CalcString('Testwert', TFormat_HEX);
  finally
    lMD5_DEC.Free;
  end;
Hashwert bei Indy: B089896DDE61B804B603F7866A9D664B
Hashwert bei DEC: 7C94514A886400F144C1B2FF80854F33


Welche Erklärung kann es dafür geben?
Liebe Grüße
Dirk Schiffler
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
880 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 12:04
Ich tippe auf automatische interne Umwandlung des übergebenen Strings. Ansi, UTF8, UnicodeString, sowas in der Richtung.
The angels have the phone box.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#3

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 12:05
Die Berechnung selbst sollte bei Beiden korrekt sein.
Ich geht da mal nicht von einem Fehler aus,

aber es kommt auch darauf an, wie der String "binär" interpretiert wird.

* Unicode (UTF-16), also 2 Byte pro Char
* ANSI, also mit der aktuellen Codepage und 1 Byte pro Char (besonder unpraktisch, wenn z.B. in deutschem, englischen, russischen oder japanischem Windows andere Codepages/Charsets verwendet werden)
* UTF-8 ... wird meistens gern benutzt

Und das kannst du dir ja im Code ansehn, was HashStringAsHex und CalcString wie intern nutzen.
* falls Parameter als "String" sind
* ansonsten wird natürlich schon bei Übergabe des Parameters konvertiert
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
647 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 13:55
B089896DDE61B804B603F7866A9D664B ist auf jeden Fall der richtige MD5 Hash für 'Testwert'. Ich vermute auch, dass die DEC Variante den Unicodestringparameter nicht korrekt verarbeitet. Dazu müsstest du mal den Quelltext der lMD5_DEC.CalcString Methode hier posten.

Mit neueren Delphi's kannst du auch die mitgeliferten Hash Routinen nutzen:
hash := System.Hash.THashMD5.GetHashString('Testwert');

Geändert von Rolf Frei (19. Mär 2024 um 13:57 Uhr)
  Mit Zitat antworten Zitat
dschiffler

Registriert seit: 25. Okt 2006
30 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 14:07
Beide Methoden haben als Parameter einen ganz normalen String.

Indy
function HashStringAsHex(const AStr: String; ADestEncoding: IIdTextEncoding = nil): String;

In der Methode wird HashString aufgerufen (als Parameter auch ein ganz normaler String).
Delphi-Quellcode:
function HashString(const ASrc: string; ADestEncoding: IIdTextEncoding = nil): TIdBytes;
var
  LStream: TStream;
begin
  LStream := TMemoryStream.Create;
  try
    WriteStringToStream(LStream, ASrc, ADestEncoding);
    LStream.Position := 0;
    Result := HashStream(LStream);
  finally
    FreeAndNil(LStream);
  end;
end;
In WriteStringToStream steht u.a. folgendes:
LBytes := ToBytes(AStr, LLength, AIndex, ADestEncoding); Ohne Encoding-Angabe ist der Standard bei Indy dann ASCII.

DEC6
function CalcString(const Value: string; Format: TDECFormatClass = nil): string; overload;
Delphi-Quellcode:
function TDECHash.CalcString(const Value: string; Format: TDECFormatClass): string;
var
  Size : Integer;
  Data : TBytes;
begin
  Result := '';
  if Length(Value) > 0 then
  begin
    {$IFDEF HAVE_STR_LIKE_ARRAY}
    Size := Length(Value) * SizeOf(Value[low(Value)]);
    Data := CalcBuffer(Value[low(Value)], Size);
    {$ELSE}
    Size := Length(Value) * SizeOf(Value[1]);
    Data := CalcBuffer(Value[1], Size);
    {$ENDIF}
    Result := StringOf(ValidFormat(Format).Encode(Data));
  end
  else
  begin
    SetLength(Data, 0);
    result := StringOf(ValidFormat(Format).Encode(CalcBuffer(Data, 0)));
  end;
end;
In der Methode wird CalcBuffer aufgerufen,
function TDECHash.CalcBuffer(const Buffer; BufferSize: Integer): TBytes; in der mit dem übergebenen Wert dann als untypisierter Buffer weitergearbeitet wird.
Liebe Grüße
Dirk Schiffler
  Mit Zitat antworten Zitat
dschiffler

Registriert seit: 25. Okt 2006
30 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 14:22
Danke Rolf.

Habe auch noch einmal verschiedene Werte getestet.

Mit System.Hash.THashMD5 von Delphi und TIdHashMessageDigest5 von Indy bekomme ich immer die gleichen Hash-Werte, so wie man es auch erwartet.

THash_MD5 von DEC6 gibt immer einen anderen Hash-Wert, was die Vermutung nahe legt, dass im DEC6 intern etwas anderes passiert.
Vielleicht kann TurboMagic etwas dazu sagen, wenn er den Thread vielleicht liest.
Liebe Grüße
Dirk Schiffler
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
880 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 14:57
Habe auch noch einmal verschiedene Werte getestet.
Auch mit Umlauten? Das wäre ggf. noch eine Stolperstelle bgzl. Ansi/Ascii und UTF8.

Ansonsten sollte die Ursache ja jetzt klar sein. Wenn bei Indy per Default der String als ANSI-String (also 1 Byte pro Zeichen) angenommen wird, und bei TDECHash.CalcBuffer der übergebene String als untypisierter Buffer ankommt, dann werden da höchstwahrscheinlich 2 Byte pro Zeichen verarbeitet.
The angels have the phone box.
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
647 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 15:55
Du müsstest auch mal abklären, was für ein Format zur Berechnung des MD5 der Webdienst benötigt. Vermutlich erwartet der nähmlich einen MD5 von einem UTF-8 string. In dem Fall musst du deinen String zuerst in UTF-8 umwandeln und dann von diesem den MD5 berechnen.

Delphi-Quellcode:
var
 b:TBytes;
 hash: string;
begin
  b := TEncoding.UTF8.GetBytes('Testwörter'); // StringOf(b) ergibt "Testwörter"
  hash := System.Hash.THashMD5.GetHashString(StringOf(b));
...
end;
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 16:55
Ich habe momentan DEC nicht installiert.
Aber wenn's immer noch so ist wie früher: Mit DEC wird doch ein Testprogramm für alle eingebauten Hash Funktionen mitgeliefert.
Hast du dort überprüft wie DEC die MD5 Testwerte berechnet? Ich nehme mal an, TurboMagic hat die Werte aus dem RFC1321 gewählt.
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#10

AW: MD5 - Unterschiede zw. Indy und DEC6

  Alt 19. Mär 2024, 17:26
Bei Indy würde ich immer enUTF8 angeben, ansonsten wird wie bereits gesagt intern immer das ASCII encoding genutzt, was einfach alle Zeichen größer $7F als '?' interpretiert - siehe TIdASCIIEncoding.GetBytes in IdGlobal.pas

Ebenso musst du bei DEC dafür sorgen, dass er einen UTF8 String hasht und nicht einen UnicodeString (UTF16) - das kann man einfach mit einem Cast auf UTF8String bewerkstelligen, hier baut der Compiler immer die notwendige Konvertierungsfunktion ein. Durch die Überladung von CalcString mit RawByteString wird dann diese aufgerufen.

Delphi-Quellcode:
  var lMD5_Indy := TIdHashMessageDigest5.Create;
  try
    var sValue := lMD5_Indy.HashStringAsHex('Tästwert', enUTF8);
    Writeln(sValue);
  finally
    lMD5_Indy.Free;
  end;

  var lMD5_DEC := THash_MD5.Create;
  try
    var sValue := lMD5_DEC.CalcString(UTF8String('Tästwert'), TFormat_HEX);
    Writeln(sValue);
  finally
    lMD5_DEC.Free;
  end;
Ausgabe (Obacht, ich hab da nen ä in den String geschmuggelt, um das mit dem UTF8 zu testen):

9C6F9390DE3580AA8717DAA21D1E3622
9C6F9390DE3580AA8717DAA21D1E3622

Laut diverser online md5 Generatoren ist das wohl richtig.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz