2016-03-03 13 views
11

Sto utilizzando DCPcrypt e SHA512 in stringhe di hash.DCPcrypt Hashing German Umlauts

Sto usando la versione da Warren Postma https://bitbucket.org/wpostma/dcpcrypt2010

Si sta lavorando bene. Tuttavia fallisce con dieresi tedesche come ä, ö, ü e probabilmente altri unicodi.

sto usando la biblioteca in questo modo:

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; 

Quando ho inserire la lettera ä mi aspetto l'uscita di essere:

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

ho controllato con quelli siti: http://hashgenerator.de/ http://passwordsgenerator.net/sha512-hash-generator/

Tuttavia ottengo:

1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A

Quindi la mia domanda è: come posso utilizzare la libreria DCPcrypt per generare hash per dieresi tedesche? Grazie

risposta

18

Questo deve essere l'errore più comune che le persone commettono con hashing e crittografia. Questi alghi operano su dati binari, ma stai passando il testo. Qualcosa da qualche parte deve codificare quel testo come binario. E quale codifica dovrebbe essere usata. Come fai a sapere che la tua biblioteca utilizza lo stesso strumento online? Non lo fai.

Quindi, ecco una regola da seguire. Mai testo hash. Basta non farlo. Codifica il testo come binario utilizzando una codifica ben definita e scelta esplicitamente. E hash quello. Ti suggerisco di codificare come UTF-8 e cancellarlo. Quindi, TEncoding.UTF8.GetBytes(...) è tuo amico qui.

Ora, guardando dettaglio reale qui, si stanno chiamando questo metodo:

procedure UpdateStr(const Str: RawByteString); 

Il parametro RawByteString, significa che il testo Unicode viene convertito in una stringa ANSI, con la tabella codici di sistema predefinita. Sono sicuro che non è quello che intendi accadere. Infatti il ​​compilatore dice questo:

[dcc32 Attenzione] W1058 fusione stringa implicita con potenziale perdita di dati da 'stringa' a 'RawByteString'

Quindi il compilatore sta dicendo che si sta facendo qualcosa di sbagliato . Devi davvero tenere a mente i messaggi del compilatore.

Ora è possibile chiamare UpdateUnicodeStr anziché UpdateStr. Ma ancora, come fai a sapere quale codifica viene utilizzata? Capita di essere la codifica interna nativa, UTF-16LE.

Ma, seguiamo la mia regola di non codificare mai il testo.

{$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. 

uscita

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

Si noti che ho semplificato il codice in altri modi. Ho rimosso la variabile stringa locale e ho lavorato direttamente con Result. Ho usato BinToHex dall'unità Classes per eseguire la conversione da digest a esadecimale. Ho cambiato anche questo codice:

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

per rimuovere l'istruzione if che non è necessario. Se un costruttore fallisce, viene sollevata un'eccezione.

Si prega di seguire la mia regola di non hash testo. Ti servirà bene!

+1

Grazie David per questa grande risposta. Apprezzo la spiegazione e sicuramente hai imparato qualcosa! – Tommy

+2

Grande. E grazie per la domanda. È bello avere una chiara dichiarazione del problema e avere l'opportunità di scrivere finalmente ciò che mi ha tormentato per un po 'di tempo. Spero che possiamo usare questo Q & A per diffondere la parola su binario e testo con hashing e crittografia! –