2016-04-10 5 views
1

Ich fange an, crypto ++ lib zu benutzen und vielleicht habe ich einige Missverständnisse.Was ist falsch an dieser sha 256 Funktion?

ich nicht erkennen, warum der folgende Code einem schlechte sha 256

# include <string> 
# include <iostream> 
# include "cryptopp/cryptlib.h" 
# include <cryptopp/sha.h> 
# include <cryptopp/hex.h> 

using namespace std; 

string sha256_hex(const string & str) 
{ 
    byte digest[CryptoPP::SHA256::DIGESTSIZE]; 
    CryptoPP::SHA256().CalculateDigest(digest, (byte*) &str[0], str.size()); 

    string ret; 
    CryptoPP::HexEncoder encoder; 
    encoder.Attach(new CryptoPP::StringSink(ret)); 
    encoder.Put(digest, sizeof(digest)); 
    encoder.MessageEnd(); 

    return ret; 
} 

int main(int argc, char *argv[]) 
{ 
    auto sha256 = sha256_hex(argv[1]); 
    cout << "str  = " << argv[1] << endl 
     << "sha 256 = " << sha256_hex(sha256) << endl; 

    return 0; 
} 

Den Befehl

./test-sha256 hello 
folgenden erzeugt

erzeugt die folgende Ausgabe

str  = hello 
sha 256 = DD9F20FF4F1DD817C567DE6C16915DC0A731A4DF51088F55CEF4CD2F89CF9620 

jedoch nach diesem Online-Rechner , die richtige sha 256 für "hello" w wäre 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824.

Also meine Frage ist, was mache ich falsch?

Ich habe eine zusätzliche Frage: Wie und wann sollte der Speicher, der von dem StringSink Objekt verwendet wird, freigegeben werden?

Vielen Dank im Voraus

Antwort

5

Rechnen Sie nicht den Hash des Hashes hier? Sie rufen sha256_hex zweimal, einmal mit argv[1] als Argument und einmal mit sha256 selbst als Argument.

+0

omg! Ich erkenne meinen Fehler; Es tut uns leid. Danke an dich und andere – lrleon

1

wahrscheinlich die meisten, sehe ich das Problem hier ist:

CryptoPP::SHA256().CalculateDigest(digest, (byte*) &str[0], str.size()); 

Sie besser Pass str.c_str(). Verwenden Sie Debugger, um zu sehen, was genau übergeben wird - übersetzt es in hello?

+0

@lrleon Ja, benutze den Debugger und.oder add print Anweisungen, das ist ein Teil der Entwicklung von Code. SO ist nicht Debugger, es ist die letzte Hilfe, nachdem Sie das grundlegende Debugging durchgeführt haben. – zaph

+0

Wie ist der von '& str [0]' und 'str.c_str()' zurückgegebene Wert anders? Sicherlich wird dies vom C++ Standard nicht garantiert, aber sind Sie jemals auf eine Implementierung gestoßen, bei der diese Ausdrücke nicht semantisch identisch sind? Ich habe keine Ahnung, warum diese "Antwort" hochgeregelt wurde. – IInspectable

+0

'& str [0]' ist korrekt, weil sie einen nichtkonstanten Zeiger liefert. 'str.c_str()' stellt einen cont-pointer zur Verfügung, und das Schreiben ist nicht definiert. – jww

2

Was den zweiten Teil der Frage:

Im Crypto ++ Pipelining system werden Filter und Senken durch das Objekt sie gebunden sind, gehört. Sie werden automatisch vom Destruktor dieses Objekts gelöscht.

Und von „Wichtige Hinweise zur Verwendung“ in ReadMe.txt:

Wenn ein Konstruktor für A einen Zeiger auf ein Objekt B (mit Ausnahme von primitiven Typen wie int und char) nimmt, dann A besitzt B und löschen B bei A Zerstörung. Wenn ein Konstruktor für A einen Verweis auf ein Objekt B annimmt, behält der Aufrufer das Eigentum an B und sollte es nicht zerstören, bis A es nicht mehr benötigt.