Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Fehler bei Übergabe eines Salts an BCrypt (https://www.delphipraxis.net/190582-fehler-bei-uebergabe-eines-salts-bcrypt.html)

Aviator 18. Okt 2016 12:31

Fehler bei Übergabe eines Salts an BCrypt
 
Hallo zusammen,

ich komme mir schon fast blöd vor eine solche Frage hier stellen zu müssen, aber irgendwie will es nicht funktionieren. :duck:

Ich habe mir die BCrypt Unit von Jose Jimeniz besorgt und möchte damit meine Passwörter, die in der Datenbank gespeichert, hashen. BCrypt erzeugt ja automatisch einen Salt, wenn keiner mitgegeben wird. Zumindest macht es diese Unit so.

Wenn ich aber keinen Salt mitgebe, dann erhalte ich ja immer wieder einen anderen Hash. Es gibt zwar die Funktion
Delphi-Quellcode:
CheckPassword()
die den Salt aus dem Hash herausliest, aber ich habe an dieser Stelle den in der Datenbank gespeicherte Hash nicht zur Verfügung (bzw. möchte ihn nicht haben). Ich will das Passwort durch die Datenbank prüfen lassen.

Also dachte ich mir, dass ich mir einen benuterabhängigen Salt ausdenke und diesem an die
Delphi-Quellcode:
HashPassword()
Funktion übergebe. Allerdings erhalte ich dann je nachdem welche Art ich ausprobiere folgende Compilermeldungen: :wiejetzt:

Versucht habe ich folgendes:
Delphi-Quellcode:
bc.HashPassword(Password, 'Test', 12); // [dcc32 Fehler] E2250 Es gibt keine überladene Version von 'HashPassword', die man mit diesen Argumenten aufrufen kann

bc.HashPassword(Password, guid.ToByteArray, 12); // [dcc32 Fehler] E2010 Inkompatible Typen: 'string' und 'System.TArray<System.Byte>'

bc.HashPassword(Password, guid.D4, 12); // [dcc32 Fehler] E2010 Inkompatible Typen: 'string' und 'System.TArray<System.Byte>'
Die Funktion HashPassword gibt es in 3 Varianten als Überladung:

Delphi-Quellcode:
class function HashPassword(const password: UnicodeString): string; overload;
class function HashPassword(const password: UnicodeString; cost: Integer): string; overload;
class function HashPassword(const password: UnicodeString; const salt: array of Byte; const cost: Integer): TBytes; overload;

class function CheckPassword(const password: UnicodeString; const expectedHashString: string): Boolean; overload;
Der Salt Parameter ist hier als array of Byte angegeben. Allerdings habe ich keine Ahnung, was ich dorthin übergeben kann, damit ich eine solche Fehlermeldung nicht erhalte. Finde auch nirgends ein Beispiel, in dem jemand mal diese Überladung genutzt hat.

Ich denke ja mal, dass das die einzige Möglichkeit ist, immer den gleichen Hash zu erhalten, wenn ich den Salt übergebe. :?:

Ich hoffe mir kann jemand bei meinem Problem helfen. Ziel wäre es, eine GUID als Salt zu übergeben.

Bin für jeden Tipp dankbar. Oder geht das irgendwie auch anders? Der Hash soll verglichen werden und der Benutzer darf weitermachen, wenn beide Hashes identisch sind.

gammatester 18. Okt 2016 13:58

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Mich wundert das Auftreten von 'System.TArray<System.Byte>', eigentlich sollte System.TGUID.D4 ein
Delphi-Quellcode:
array[0..7] of byte
sein. Leider kann ich die Unit nicht übersetzen, wegen Pointerarithmetik mit UIntPtr.

Was passiert denn wenn Du folgendes testest;
Delphi-Quellcode:
const
  mysalt = array[0..7] of byte = (0,1,2,3,4,5,6,7);

..

  HashPassword(Password, mysalt,12);
Wenn das übersetzbar ist, kann man notfalls ein Konstrukt wie dieses verwenden:
Delphi-Quellcode:
var
  g: TGuid;
  aa: array[0..7] of byte;
begin
  move(g.d4, aa, sizeof(aa));
  HashPassword(Password, aa,12);
Eine direkte Zuweisung
Delphi-Quellcode:
aa := g.d4
funktioniert nicht, da die beiden Typen
Delphi-Quellcode:
array[0..7] of byte;
inkompatibel sind.

Aviator 18. Okt 2016 14:05

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Zitat:

Zitat von gammatester (Beitrag 1351228)
Was passiert denn wenn Du folgendes testest;
Delphi-Quellcode:
const
  mysalt = array[0..7] of byte = (0,1,2,3,4,5,6,7);

..

  HashPassword(Password, mysalt,12);

Hallo gammatester,

leider der gleiche Fehler. [dcc32 Fehler] E2010 Inkompatible Typen: 'string' und 'System.TArray<System.Byte>'

Delphi-Quellcode:
GUID.D4
ist auch ein
Delphi-Quellcode:
array[0..7] of byte
. Deshalb wundert es mich, dass das nicht funktioniert. Ich werde mal noch ein dynamisches Array of Byte ausprobieren und mich dann nochmal melden. Aber ich vermute, dass da der gleiche Fehler auftritt.

EDIT: Ja gleiches Problem bei einem dynamischen Array. Warum sollte das auch plötzlich funktionieren.

gammatester 18. Okt 2016 14:20

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Mich beschleicht das Gefühl, daß nicht nur das
Delphi-Quellcode:
array of byte
Probleme macht. Welchen
Delphi-Quellcode:
type
hat denn Password? Oder anders gefragt, welche Meldung gibt es bei
Delphi-Quellcode:
const
  mysalt: array[0..7] of byte = (0,1,2,3,4,5,6,7);
  mypw: unicodestring = 'Test';

..

  HashPassword(mypw, mysalt,12);

SebastianZ 18. Okt 2016 14:25

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Zitat:

Zitat von Aviator (Beitrag 1351204)
Hallo zusammen,

Versucht habe ich folgendes:
Delphi-Quellcode:
bc.HashPassword(Password, 'Test', 12); // [dcc32 Fehler] E2250 Es gibt keine überladene Version von 'HashPassword', die man mit diesen Argumenten aufrufen kann


Delphi-Quellcode:
class function HashPassword(const password: UnicodeString; cost: Integer): string; overload;

Naja, wenn die Funktion so aussieht:
Delphi-Quellcode:
class function HashPassword(const password: UnicodeString; cost: Integer): string; overload;
dann ist dein Aufruf falsch. Korrekt wäre:
Delphi-Quellcode:
..
  hash := bc.HashPassword('test', 123);
..
selbes gilt für deine anderen Aufrufe. Ich weiß nicht was das Password vorder bei machen soll?

Kurze Zwischenfrage: Muss es genau diese Funktion sein?
Was spricht gegen THashBobJenkins.GetHashvalue aus der System.Hash?

Und wenns mit Salt sein soll kann man sich ja eine kleine eigene Routine machen

zB (ungetestet)
Delphi-Quellcode:
function GibMirHash(const AData: String; const ASalt: Integer): Integer;
begin
  Result := THashBobJenkins.GetHashValue(PChar(AData)^, AData.Length * SizeOf(Char), ASalt);
end;
hoffe damit ist dir geholfen ;)

gammatester 18. Okt 2016 14:33

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Oder weist Du die Ergebnisse bc.HashPassword einem string zu?
Delphi-Quellcode:
mystr := bc.HashPassword(Password, guid.D4, 12);
Da die Deklaration so aussieht
Delphi-Quellcode:
//If you want to handle the cost, salt, and encoding yourself, you can do that.
class function HashPassword(const password: UnicodeString; const salt: array of Byte; const cost: Integer): TBytes; overload;
erhälts Du ein Ergebnis vom Typ TBytes, was manche Fehlermeldungen erklären würde.

Aviator 18. Okt 2016 15:12

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Zitat:

Zitat von gammatester (Beitrag 1351234)
Oder weist Du die Ergebnisse bc.HashPassword einem string zu?
Delphi-Quellcode:
mystr := bc.HashPassword(Password, guid.D4, 12);
Da die Deklaration so aussieht
Delphi-Quellcode:
//If you want to handle the cost, salt, and encoding yourself, you can do that.
class function HashPassword(const password: UnicodeString; const salt: array of Byte; const cost: Integer): TBytes; overload;
erhälts Du ein Ergebnis vom Typ TBytes, was manche Fehlermeldungen erklären würde.

Oh mann. :oops:

Das war es. Der Rückgabetyp dieser Funktion ist ein anderer. Manchmal sieht man den Wald vor lauter Bäuimen nicht. Die Frage ist nur, warum die Funktion einen anderen Rückgabetyp hat.

So funktioniert es jetzt.

Delphi-Quellcode:
function HashPassword(const Password: string): string;
var
  bc: TBCrypt;
  guid: TGUID;
  tb: TBytes;
begin
  Result := EmptyStr;
  bc := TBCrypt.Create;
  try
  guid := TGUID.Create;
  tb := bc.HashPassword(Password, guid.ToByteArray, 12);
  Result := TEncoding.Unicode.GetString(tb);
  finally
    bc.Free;
  end;
end;
EDIT: Etwas zu früh gefreut. Die Zeile
Delphi-Quellcode:
Result := TEncoding.Unicode.GetString(tb);
macht noch ein paar Probleme. Da kommt im Moment nur Müll raus.

Wie kann ich TBytes in String umwandeln, sodass nochmal ein Hash rauskommt?

mjustin 18. Okt 2016 15:37

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Zitat:

Zitat von SebastianZ (Beitrag 1351232)
Was spricht gegen THashBobJenkins.GetHashvalue aus der System.Hash?

Das ist eine interessante Frage. Ich habe BobJenkinsHash auch mal als Antwort auf die Frage "How do I hash a string with Delphi?" vorgeschlagen. Da erhielt ich den Kommentar, Bob Jenkins sei keine kryptografische Hash-Funktion.

Es ist auch nachvollziehbar: für einen schwer zu knackenden Hash-Wert muss der Aufwand hoch sein, und für einen Hash-Wert der nur für ein TDictionary benutzt wird soll das Hashen schnell gehen. Unterschiedliche Anforderungen.

Aviator 18. Okt 2016 15:49

AW: Fehler bei Übergabe eines Salts an BCrypt
 
Hmm. Keine Ahnung was dagegen spricht. Ich habe mir BCrypt jetzt ausgesucht.

Ich wollte eben einen Hash Algorithmus haben, der mir immer einen String der gleichen Länge zurückgibt und der auch sicher ist. MD5 sollte man ja nicht mehr verwenden wegen der möglichen Kollisionen.

Dieser THashBobJenkins gibt ja wie ich das sehen nur einen Integer Wert aus. Irgendwie habe ich da so die Befürchtung, dass der relativ einfach zu knacken wäre.

Welche Alternativen zu BCrypt und THashBobJenkins würde es denn noch geben für die eine entsprechende Klasse bereits existiert?

Am liebsten wäre es mir allerdings, wenn ich den BCrypt Algorithmus so zum Laufen bekommen würde.


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