2016-03-03 5 views
11

Ich verwende DCPcrypt und SHA512 Hash-Strings.DCPcrypt Hashing deutsche Umlaute

Ich verwende die Version von Warren Postma https://bitbucket.org/wpostma/dcpcrypt2010

Es funktioniert gut. Allerdings fehlen deutsche Umlaute wie ä, ö, ü und wahrscheinlich andere Unicodes.

Ich verwende die Bibliothek wie folgt aus:

function TForm1.genhash(str: string): string; 
var 
    Hash : TDCP_sha512; 
    Digest: array[0..63] of byte; 
    i: integer; 
    s: string; 
begin 
    s:= ''; 
    hash := TDCP_sha512.Create(nil); 
    if hash<>nil then 
    begin 
    try 
     Hash.Init; 
     Hash.UpdateStr(str); 
     Hash.Final(Digest); 

     for i:= 0 to length(Digest)-1 do 
     s:= s + IntToHex(Digest[i],2); 

    finally 
     hash.free; 
    end; 

    end; 
    Result := s; 
end; 

Wenn ich Eingabe der Buchstaben ä i erwarten, dass der Ausgang zu sein:

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

Ich habe es mit denen, Standorte: http://hashgenerator.de/ http://passwordsgenerator.net/sha512-hash-generator/

aber ich bekomme:

1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A

Also meine Frage ist: Wie kann ich die DCPcrypt Bibliothek verwenden Hashes für Deutsch Umlaute zu generieren? THanks

Antwort

18

Dies muss der einzige häufigste Fehler sein, den Menschen mit Hashing und Verschlüsselung machen. Diese Algos arbeiten mit binären Daten, aber Sie geben Text weiter. Etwas muss diesen Text als Binärcode kodieren. Und welche Kodierung sollte verwendet werden. Woher wissen Sie, dass Ihre Bibliothek das gleiche wie das Online-Tool verwendet? Du nicht.

Also, hier ist eine Regel für Sie zu folgen. Niemals Hash-Text. Tu es einfach nicht. Codieren Sie den Text mit einer wohldefinierten, explizit gewählten Codierung als Binärcode. Und hash das. Ich schlage vor, Sie kodieren als UTF-8 und Hash das. Also, ist dein Freund hier.

Jetzt, am tatsächlichen Detail suche hier, Sie rufen diese Methode:

procedure UpdateStr(const Str: RawByteString); 

Der RawByteString Parameter, bedeutet, dass die Unicode-Text in eine Zeichenfolge ANSI umgewandelt wird, mit der Standard-System-Codepage. Ich bin mir sicher, dass das nicht beabsichtigt ist. Tatsächlich sagt der Compiler dies:

[DCC32 Warning] W1058 Implizite String-Umwandlung mit potenziellem Datenverlust von 'string' auf 'RawByteString'

So ist der Compiler sagt Ihnen, dass Sie etwas falsch zu machen sind . Sie müssen wirklich auf Compiler-Nachrichten achten.

Nun könnten Sie UpdateUnicodeStr statt UpdateStr anrufen. Aber wieder, woher weißt du, welche Kodierung verwendet wird? Es ist zufällig die native interne Codierung, UTF-16LE.

Aber, lasst uns meiner Regel folgen, niemals Text zu kodieren.

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Classes, DCPsha512; 

function genhash(str: string): string; 
var 
    Bytes: TBytes; 
    Hash: TDCP_sha512; 
    Digest: array[0..63] of byte; 
begin 
    Bytes := TEncoding.UTF8.GetBytes(str); // encode text as UTF-8 bytes 

    hash := TDCP_sha512.Create(nil); 
    try 
    Hash.Init; 
    Hash.Update(Pointer(Bytes)^, Length(Bytes)); 
    Hash.Final(Digest); 
    finally 
    hash.Free; 
    end; 

    // convert the digest to a hex hash string 
    SetLength(Result, Length(Digest)*2); 
    BinToHex(Digest, PChar(Result), Length(Digest)); 
end; 

begin 
    Writeln(genhash('ä')); 
    Readln; 
end. 

Ausgabe

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

Bitte beachte, dass ich den Code in einigen anderen Arten vereinfacht. Ich entfernte die lokale String-Variable und arbeitete direkt mit Result. Ich habe BinToHex von der Classes Einheit verwendet, um die Umwandlung von Digest in Hex durchzuführen. Ich habe auch diesen Code:

hash := TDCP_sha512.Create(nil); 
if hash<>nil then 
    .... 

die if Anweisung zu entfernen, die nicht benötigt wird. Wenn ein Konstruktor fehlschlägt, wird eine Ausnahme ausgelöst.

Bitte folgen Sie meiner Regel nie Hash-Text. Es wird dir gut dienen!

+1

Danke David für diese großartige Antwort. Schätze die Erklärung und habe definitiv etwas gelernt! – Tommy

+2

Großartig. Und danke für die Frage. Es ist schön, eine klare Aussage über das Problem zu bekommen und endlich die Möglichkeit zu haben, etwas niederzuschreiben, was mich schon seit einiger Zeit ärgert. Ich hoffe, dass wir dieses Q & A nutzen können, um mit Hashing und Verschlüsselung das Wort über Binär und Text zu verbreiten! –