Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   SHA-3 von Wolfang Ehrhardt (https://www.delphipraxis.net/194851-sha-3-von-wolfang-ehrhardt.html)

Ghostwalker 16. Jan 2018 08:10

SHA-3 von Wolfang Ehrhardt
 
Moinmoin,

bin etwas verwirrt. Ich wollte, zum sicheren Speichern von Passwörtern in einer DB, die Passwörter Hashen.

Ok,..aktueller Stand dürfte SHA3 sein und fand die Implementierung von Wolfgang Ehrhardt. Hab das ganze auch ohne große Sache integrieren können. Nur funktionieren wills nicht so wirklich. Bei jedem Programmstart bekomme ich, obwohl die Eingangsdaten identisch zu den anderen Aufrufen sind, einen anderen Hash ??

Delphi-Quellcode:
function CreateHash(aString:string):string;
var
  Context : THashContext;
  Digist : TSHA3_512Digest;
  //bytes  : Array of Byte;
  size   : Integer;
  Bytes  : TBytes;

begin
  SHA3_512Init(Context);
  size := aString.Length * SizeOf(Char);
  Bytes := TEncoding.Default.GetBytes(aString);
  SHA3_512Update(Context,@bytes,size);
  SHA3_512Final(Context,Digist);
  result := Base64Str(@Digist,sizeof(Digist));
end;
Dabei ist aString immer PWD+Salz. Aber wie gesagt, bekomme ich bei jedem Start des Programms, einen anderen
Hash, obwohl PWD+Salz immer gleich ist.

Findet ihr hier einen Fehler ?

Danke schonmal :)

TiGü 16. Jan 2018 08:21

AW: SHA-3 von Wolfang Ehrhardt
 
Ich kenne die Biblothek nicht, aber müsste es nicht eher so lauten?

Delphi-Quellcode:
SHA3_512Update(Context,@Bytes, Length(Bytes));

Ghostwalker 16. Jan 2018 08:29

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von TiGü (Beitrag 1391030)
Ich kenne die Biblothek nicht, aber müsste es nicht eher so lauten?

Delphi-Quellcode:
SHA3_512Update(Context,@Bytes, Length(Bytes));

Hmm...sollte aufs gleiche rauskommen. Habs grad mal geprüft, das verhalten ändert sich nicht.
Bei jedem Programmstart bekomm ich unterschiedliche Hashes.

TiGü 16. Jan 2018 08:44

AW: SHA-3 von Wolfang Ehrhardt
 
Hast du kontrolliert, ob Bytes immer gleich ist?
Vielleicht ergibt sich da schon die Abweichung?

Ghostwalker 16. Jan 2018 09:00

AW: SHA-3 von Wolfang Ehrhardt
 
Die Bytes die rein gehen sind immer die gleichen. Das was raus kommt (digist ist auch ein Byte-Array) ist immer anders.

samso 16. Jan 2018 09:02

AW: SHA-3 von Wolfang Ehrhardt
 
Vielleicht so:

Delphi-Quellcode:
SHA3_512Update(Context,Pointer(bytes),Length(bytes));

Ghostwalker 16. Jan 2018 09:06

AW: SHA-3 von Wolfang Ehrhardt
 
Autsch.....:wall::wall:

das
Delphi-Quellcode:
SHA3_512Update(Context,@bytes,size);
muss
Delphi-Quellcode:
SHA3_512Update(Context,@bytes[0],size);
sein.

Er braucht die Adresse des 1. Bytes im Array, nicht die Adresse der Array-Variable.

Trotzdem Danke :)

gammatester 16. Jan 2018 09:20

AW: SHA-3 von Wolfang Ehrhardt
 
Du bist ein Opfer der Compiler-Magie gewerden. Nach der Deklaration
Delphi-Quellcode:
Bytes : TBytes;
ist Bytes (natürlich?) ein Pointer und mit
Delphi-Quellcode:
@bytes
berechnest Du nicht den Hash von Bytes sondern den Hash des Pointers (und der ändert sich in der Regel, weil ja die Speicheraddresse sich je nach Allokation ändert).

Mit der korrigierten Version
Delphi-Quellcode:
program t_dp_ex;
uses
  system.hash, system.sysutils,
  btypes, mem_util, hash, sha3_512;

{$i std.inc}

{$ifdef APPCONS}
  {$apptype console}
{$endif}

{-----------------------------------------}
function CreateHash(aString:string):string;
var
  Context : THashContext;
  Digist : TSHA3_512Digest;
  //bytes : Array of Byte;
  size : Integer;
  Bytes : TBytes;

begin
  SHA3_512Init(Context);
  size := aString.Length * SizeOf(Char);
  Bytes := TEncoding.Default.GetBytes(aString);
  SHA3_512Update(Context,bytes,size);
  SHA3_512Final(Context,Digist);
  result := Base64Str(@Digist,sizeof(Digist));
end;

begin
  writeln(CreateHash('abc1234'));
end.
Code:
erhalte ich immer das gleiche Ergebnis:
G:\CRC_HASH>t_dp_ex.exe
Zzvn3sQanFpmGDltaWoEMPBRm4tEtBzAP22pOKoe3X1TCY4VN5K8a0cFNWBDOYo8oNInfUYU/tNJWDFf
XXftyA==

G:\CRC_HASH>t_dp_ex.exe
Zzvn3sQanFpmGDltaWoEMPBRm4tEtBzAP22pOKoe3X1TCY4VN5K8a0cFNWBDOYo8oNInfUYU/tNJWDFf
XXftyA==

G:\CRC_HASH>t_dp_ex.exe
Zzvn3sQanFpmGDltaWoEMPBRm4tEtBzAP22pOKoe3X1TCY4VN5K8a0cFNWBDOYo8oNInfUYU/tNJWDFf
XXftyA==
Gruß Gammatester

samso 16. Jan 2018 09:32

AW: SHA-3 von Wolfang Ehrhardt
 
Ich kann weiterhin nicht glauben, dass size=Length(Bytes) gilt. Wieso soll die Länge des Strings nach der Umkodierung die Größe (in Bytes) des Strings vor der Umkodierung sein? Kann mir das jemand erklären?

Edit:
Ah, jetzt ist der Groschen gefallen. Ich dachte, da wird nach Ansi umkodiert. Anscheinen wird aber wohl nur kopiert.

Edit2: Unsinn: Doch, TEncoding.Default.GetBytes wandelt nach Ansi um.

gammatester 16. Jan 2018 09:44

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von samso (Beitrag 1391048)
Ich kann weiterhin nicht glauben, dass size=Length(Bytes) gilt. Wieso soll die Länge des Strings nach der Umkodierung die Größe (in Bytes) des Strings vor der Umkodierung sein? Kann mir das jemand erklären?

Edit:
Ah, jetzt ist der Groschen gefallen. Ich dachte, da wird nach Ansi umkodiert. Anscheinen wird aber wohl nur kopiert.

Wie auch immer: Falls nicht gewährleistet ist, daß Bytes weniger als 64 K groß ist, sollten das Hashen mit
Delphi-Quellcode:
SHA3_512UpdateXL
durchgeführt werden.

Mit length(Bytes) erhalte ich übrigens auch ein anderes Ergebnis für meinen Teststring.

Uwe Raabe 16. Jan 2018 10:09

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von samso (Beitrag 1391048)
Ich kann weiterhin nicht glauben, dass size=Length(Bytes) gilt. Wieso soll die Länge des Strings nach der Umkodierung die Größe (in Bytes) des Strings vor der Umkodierung sein? Kann mir das jemand erklären?

Du hast vollkommen Recht:
Delphi-Quellcode:
Length(bytes)
wäre hier korrekt. Je nach Encoding ist die Länge der Bytes in der Regel kürzer als die vorher berechnete Size. Demnach haben wir hier einen klassischen Buffer-Overrun, wie er bei Pointer-Programmierung leider sehr häufig vorkommt. Damit werden auch unbestimmte Bytes mit in den Hash eingerechnet, die in den TBytes gar nicht vorkommen, sondern zufällig im Speicher dahinter liegen (deshalb auch der Unterschied zwischen der Verwendung von Size und Length(Bytes)). Bei Size ist das Ergebnis daher auch nicht deterministisch.

Eine aktuelle Implementierung würde vermutlich gleich auf TBytes aufsetzen und wäre damit auf die Angabe der Puffergröße gar nicht angewiesen.

gammatester 16. Jan 2018 10:25

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1391055)
Eine aktuelle Implementierung würde vermutlich gleich auf TBytes aufsetzen und wäre damit auf die Angabe der Puffergröße gar nicht angewiesen.

Ich sehe nicht wie das mit BP7 oder VP21 kompatibel sein soll. Außerdem habe ich keine Lust und Zeit, für alle möglichen Eingabetypen separate Funktionen zu schreiben. Im übrigen ist die Form Init/Update/Final mit Pointern ziemlich verbreitet bei Hash-Implementationen (wahrscheinlich durch C beeinflußt).

Uwe Raabe 16. Jan 2018 10:43

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von gammatester (Beitrag 1391058)
Ich sehe nicht wie das mit BP7 oder VP21 kompatibel sein soll.

Soll es ja auch gar nicht.

Zitat:

Zitat von gammatester (Beitrag 1391058)
Außerdem habe ich keine Lust und Zeit, für alle möglichen Eingabetypen separate Funktionen zu schreiben.

Das ist ja auch dein gutes Recht.

Zitat:

Zitat von gammatester (Beitrag 1391058)
Im übrigen ist die Form Init/Update/Final mit Pointern ziemlich verbreitet bei Hash-Implementationen (wahrscheinlich durch C beeinflußt).

Eine weite Verbreitung ist aber nicht wirklich ein Qualitätsmerkmal. Der oben angesprochene Fehler ist doch ein ziemlich eindeutiges Indiz.

gammatester 16. Jan 2018 11:10

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1391061)
Zitat:

Zitat von gammatester (Beitrag 1391058)
Ich sehe nicht wie das mit BP7 oder VP21 kompatibel sein soll.

Soll es ja auch gar nicht.

Aber sicher soll es das. Die meisten direkten Rückmeldungen und Optimierunsvorschläge erhalte ich übrigens für VP21, Delphi3 und TP6(!) Vielleicht auch bedingt dadurch, daß die Funktionen praktisch für alle Kompiler nutzbar sind.
Zitat:

Zitat von Uwe Raabe (Beitrag 1391061)
Zitat:

Zitat von gammatester (Beitrag 1391058)
Im übrigen ist die Form Init/Update/Final mit Pointern ziemlich verbreitet bei Hash-Implementationen (wahrscheinlich durch C beeinflußt).

Eine weite Verbreitung ist aber nicht wirklich ein Qualitätsmerkmal. Der oben angesprochene Fehler ist doch ein ziemlich eindeutiges Indiz.

Der oben angesprochene Fehler ist mM ein Resultat der undurchsichtigen Kompiler-Magie: wenn man nicht verschleiern würde das TBytes kein Array sondern ein Pointer auf ein Array ist, wäre der Fehler offensichtlich.

Uwe Raabe 16. Jan 2018 11:22

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von gammatester (Beitrag 1391063)

Aber sicher soll es das. Die meisten direkten Rückmeldungen und Optimierunsvorschläge erhalte ich übrigens für VP21, Delphi3 und TP6(!) Vielleicht auch bedingt dadurch, daß die Funktionen praktisch für alle Kompiler nutzbar sind.[/QUOTE]

.. oder weil die Benutzung durch neue Compiler unnötig umständlich ist?

Ich habe ja nicht behauptet, daß die bestehenden Methoden durch neue ersetzt werden sollen. Vielmehr hatte ich an overloaded-Versionen für TBytes als Alternative gedacht. So diese denn unter bestimmten Compilern nicht unterstütz werden, kann man die ja durch conditional defines ausblenden.

Allerdings habe ich jetzt auch keine Lust, über den Sinn oder Unsinn von alten oder anderen Compilern zu diskutieren. Insofern steht es dir natürlich frei, deine Routinen so zu gestalten wie du es für richtig hältst.

Ghostwalker 16. Jan 2018 11:24

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1391061)
Der oben angesprochene Fehler ist doch ein ziemlich eindeutiges Indiz.

Der Fehler hat eher was mit Wäldern und Bäumen zu tun, als mit irgend etwas anderem :)

Das in der Bibleothek ein Pointer und die Größe erwartet wird, ist völlig normal. Die Bibleothek soll
ja ein möglichst breites Publikum ansprechend und das bedingt verschiedene Comiler und Compilerversionen.

Btw. hier nun der entgültige Code, der, soweit ich das im Moment beurteilen kann, auch korrekt läuft.
Delphi-Quellcode:
  if (length(trim(ftoHash)) = 0) then exit;
  SHA3_512Init(fcontext);
  fbytes := TEncoding.GetEncoding('UTF-16').GetBytes(fToHash);
  fSize := TEncoding.GetEncoding('UTF-16').GetByteCount(fToHash);
  SHA3_512Update(fcontext,@fbytes[0],fsize);
  SHA3_512Final(fcontext,fdigist);
  fHash := Base64Str(@fdigist,sizeof(fdigist));

gammatester 16. Jan 2018 11:30

AW: SHA-3 von Wolfang Ehrhardt
 
Zitat:

Zitat von Ghostwalker (Beitrag 1391065)
Btw. hier nun der entgültige Code, der, soweit ich das im Moment beurteilen kann, auch korrekt läuft.

Wie schon gesagt: Sicherheitshalber solltest Du
Delphi-Quellcode:
SHA3_512UpdateXL
benutzen.

Uwe Raabe 16. Jan 2018 12:01

AW: SHA-3 von Wolfang Ehrhardt
 
Das ist aber doch unnötig kompliziert, oder? (auch eine Art von Code-Obfuscation)
Delphi-Quellcode:
  fbytes := TEncoding.GetEncoding('UTF-16').GetBytes(fToHash);
  fSize := TEncoding.GetEncoding('UTF-16').GetByteCount(fToHash);
Warum nicht gleich so?
Delphi-Quellcode:
 
  fbytes := TEncoding.GetEncoding('UTF-16').GetBytes(fToHash);
  fSize := Length(fBytes);
Oder so?
Delphi-Quellcode:
 
  fbytes := TEncoding.Unicode.GetBytes(fToHash);
  fSize := Length(fBytes);
Wobei der ByteCount von Unicode auch wieder nur
Delphi-Quellcode:
CharCount * SizeOf(Char)
ist. TEncoding.Default ist von den aktuellen Windows-Einstellungen abhängig, also eher ungünstig. Etwas sparsamer und trotzdem allgemein gültig wäre da noch UTF8:
Delphi-Quellcode:
 
  fbytes := TEncoding.UTF8.GetBytes(fToHash);
  fSize := Length(fBytes);
Wenn die Hashes auch anderweitig verwendet werden, muss sowieso das Encoding bekannt gemacht werden. Sonst kann niemand was damit anfangen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 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