Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   DEC Design Frage (https://www.delphipraxis.net/210083-dec-design-frage.html)

TurboMagic 27. Feb 2022 14:43

DEC Design Frage
 
Hallo,

wer den Developer Branch von https://github.com/MHumm/DelphiEncry...ee/development
verfolgt wird mitbekommen haben, dass die Arbeiten an der nächsten version am Laufen sind.

Nur hab' ich dazu heute mal eine Design Frage bzw. rätsele etwas herum, es ist aber auch Java im Spiel.

Ich habe eine https://de.wikipedia.org/wiki/Bcrypt Umsetzung im Prinzip schon am Laufen,
und habe eine Klassenmethode hinzugefügt, bei denen alle Parameter als RawByteStrigns übergeben werden.
Die entsprechenden Unit Tests mit Testdaten aus der Quelle aus der ich den Code her habe funktionieren fehlerfrei.

Nur ist da jetzt die Idee, dieselbe Methode auch mit normalem string für das zu hashende Passwort anzubieten
und da komme ich etwas ins schleudern. Delphi's string ist ja UTF16 und soweit ich weiß auch Strings in Java, richtig?
Ich dachte (hab's noch nicht getestet), dass da andere Testdaten nötig wären, weil der string ja binär anders codiert ist.
Im Wikipedia Artikel ist diese Java Bibliothek verlinkt: http://www.mindrot.org/projects/jBCrypt/
die string als Parameter nutzt, aber genau die selben Testdaten wie ich.

Jetzt frage ich mich halt: wie kann das gehen? Zumindest damals war das wohl meistens UTF16 intern, in neueren Java Versionen sind
die wohl auf eine Mischung umgestiegen:
- für strings die nur ASCII Zeichen enthalten wird intern ein Bytearray benutzt
- für andere Strings UTF16

Und die Frage: wie soll ich damit umgehen?
Da meine RawByteString Tests ja alle bestanden werden davon ausgehen, dass ich einfach neue Überladene Methoden mit normalen
strings schreibe und neue testdaten synthetisiere?

Grüße
TurboMagic

Uwe Raabe 27. Feb 2022 15:22

AW: DEC Design Frage
 
Zitat:

Zitat von TurboMagic (Beitrag 1502759)
Nur ist da jetzt die Idee, dieselbe Methode auch mit normalem string für das zu hashende Passwort anzubieten
und da komme ich etwas ins schleudern. Delphi's string ist ja UTF16 und soweit ich weiß auch Strings in Java, richtig?
Ich dachte (hab's noch nicht getestet), dass da andere Testdaten nötig wären, weil der string ja binär anders codiert ist.

Die interne Darstellung eines Strings innerhalb einer Programmiersprache sollte keinen Einfluss auf das Ergebnis der Verschlüsselung haben. Ob ich ein Passwort als ShortString, AnsiString oder WideString angebe, sollte immer auf den gleichen Hash hinaus laufen. Ansonsten wäre das Verfahren vollkommen unbrauchbar. Deswegen würde ich auch nicht RawByteString verwenden, weil das immer noch diese String Notation verwendet, sondern immer mit TBytes arbeiten. Der Algorithmus arbeitet ja auch mit Zahlen (Bytes) und nicht mit Buchstaben.

TurboMagic 27. Feb 2022 16:25

AW: DEC Design Frage
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1502762)
Zitat:

Zitat von TurboMagic (Beitrag 1502759)
Nur ist da jetzt die Idee, dieselbe Methode auch mit normalem string für das zu hashende Passwort anzubieten
und da komme ich etwas ins schleudern. Delphi's string ist ja UTF16 und soweit ich weiß auch Strings in Java, richtig?
Ich dachte (hab's noch nicht getestet), dass da andere Testdaten nötig wären, weil der string ja binär anders codiert ist.

Die interne Darstellung eines Strings innerhalb einer Programmiersprache sollte keinen Einfluss auf das Ergebnis der Verschlüsselung haben. Ob ich ein Passwort als ShortString, AnsiString oder WideString angebe, sollte immer auf den gleichen Hash hinaus laufen. Ansonsten wäre das Verfahren vollkommen unbrauchbar. Deswegen würde ich auch nicht RawByteString verwenden, weil das immer noch diese String Notation verwendet, sondern immer mit TBytes arbeiten. Der Algorithmus arbeitet ja auch mit Zahlen (Bytes) und nicht mit Buchstaben.

Ja und nein: es ist für den BCrypt scheinbar nirgends definiert, wie Zeichen in ein Byte-Format mit dem der Algorithmus dann sicherlich intern arbeitet konvertiert werden. Und an der Stelle ist es dann halt schon relevant, wie der String intern codiert ist,
da man ja von den eingegebenen Zeichen irgendwie zu den Bytes kommen muss...
Das ist bei RawByteString string ja relativ einfach, aber beim normalen string würde was anderes als Hash raus kommen, weil es intern
anders repräsentiert wird.
Einfach mal angenommen das Passwort wäre 'A' dann kommt einmal 0x41 raus und im Fall des normalen strings 0x00 0x41.
Oder was verstehe ich hier falsch?

Uwe Raabe 27. Feb 2022 22:50

AW: DEC Design Frage
 
Ich finde, du gehst das Problem da falsch an, und die Wahl von RawByteString ist da ganz wesentlicher Bestandteil der Ursache. RawByteString übernimmt die Zeichen byteweise wie sie sind. Gibt man einen AnsiString rein, wird er so übernommen. Nimmt man einen UTF8string, kommt auch dieser unbehandelt zum Einsatz. Damit macht sich die Implementierung vom tatsächlichen Encoding des RawByteString (und das gibt es!) abhängig.

Problematisch wird es halt bei den Zeichen > $7f, denn darunter sind beide Codierungen gleich. Mit Passwörtern im ASCII-Bereich wird man keine Probleme feststellen. Verwendet man aber z.B. Umlaute wird man Unterschiede unter Windows mit einer JAVA-Referenz auf Linux feststellen (übrigens auch mit JAVA auf Windows).

Um das Problem diverser interner String-Codierungen plattformübergreifend zu lösen, muss man sich auf ein Encoding einigen. Herausgekommen ist dabei UTF8, wie man aus einer simplen JAVA-Implementation herauslesen kann:
Code:
passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
Wobei hier passwordb als Bytearray deklariert ist.

Die straight forward Übersetzung in Delphi wäre somit die Verwendung von TBytes für die internen Berechnungen und die Umwandlung des String-Password mittels TEncoding.UTF8.GetBytes.

OT: Ich habe nie verstanden, warum bei Hash, Crypt und sonstigen Rechnungen mit Strings, seien es Ansi oder RawByte, gearbeitet wird. Das ist doch geradezu eine Einladung für fehlerhafte Verwendung.

Sinspin 28. Feb 2022 06:27

AW: DEC Design Frage
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1502778)
Ich finde, du gehst das Problem da falsch an

+1

Zitat:

Zitat von Uwe Raabe (Beitrag 1502778)
OT: Ich habe nie verstanden, warum bei Hash, Crypt und sonstigen Rechnungen mit Strings, seien es Ansi oder RawByte, gearbeitet wird. Das ist doch geradezu eine Einladung für fehlerhafte Verwendung.

Das sehe ich genauso. Aus nichts als Bytes hat die interne Verarbeitung zu bestehen.
Wenn ein Password eingeben wird, dieses als erstes in ASCII convertieren und nur mit dessen Bytes arbeiten. Im Endeffekt ist es ja auch wurst was als Password eingegeben wird. Es muss intern immer und überall die gleiche Darstellung entstehen. Auf jeder Maschiene oder Programmiersprache.

TurboMagic 28. Feb 2022 07:02

AW: DEC Design Frage
 
Hallo,

danke für die letzten beiden Antworten!

1. Die interne Verarbeitung basiert schon auf Bytes.
2. Das mit dem Konvertieren nach UTF8 und in ein Byte Array
hatte ich so nicht gesehen, das ist aber genau der Hinweis
der mir gefehlt hatte. :-)
Damit müsste ich weiter kommen.


Grüße
TurboMagic


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