C/C++: Kryptografische Hashes mit libtomcrypt berechnen

English Deutsch

Problem:

Du möchtest einen Hash eines beliebigen Strings in C/C++ berechnen. LibTomCrypt ist unter der WTFPL-Lizenz verfügbar und daher eine gute Wahl für kommerzielle und nicht-kommerzielle Projekte.

Lösung

Dieser Beitrag beschreibt eine minimalistische Lösung. Weitere Informationen findest du in der offiziellen Dokumentation.

Hier ist ein minimales C-Beispiel zum Hashen eines C-Strings.

hash_sha1_c.c
#include <tomcrypt.h>
/**
 * Hasht eine gegebene Byte-Sequenz mit dem SHA1-Algorithmus
 * @param input Zeiger auf die Eingabesequenz
 * @param inputSize Größe der Eingabesequenz
 * @return Ein per malloc reservierter Zeiger auf die resultierenden Daten. 20 Bytes lang.
 */
unsigned char* hashSHA1(const char* input, unsigned long inputSize) {
    //Initialisierung
    unsigned char* hashResult = (unsigned char*)malloc(sha1_desc.hashsize);
    //Zustandsvariable für den Hash initialisieren
    hash_state md;
    sha1_init(&md);
    //Text verarbeiten - daran erinnern, dass process() mehrfach aufgerufen werden kann
    sha1_process(&md, (const unsigned char*) input, inputSize);
    //Hash-Berechnung abschließen
    sha1_done(&md, hashResult);
    // Ergebnis zurückgeben
    return hashResult;
}

Nach der Verwendung dieser Funktion musst du den von ihr reservierten und zurückgegebenen Speicher mit free() freigeben.

Andere Hash-Algorithmen

Um einen anderen Algorithmus zu verwenden (z.B. SHA256 oder MD5), müssen zwei Dinge ersetzt werden: 1. Der Hash-Name (in diesem Fall sha1_) durch sein Gegenstück (jedes Vorkommen ersetzen!) 2. Die Hash-Größe für SHA1 beträgt 20 Bytes, für andere Hashes kann sie abweichen, z.B. 32 für SHA256

Siehe die Dokumentation, Abbildung 4.1 „Built-In Software Hashes“ für eine Liste gültiger Hash-Deskriptoren und der zugehörigen Hash-Größen.

C++

Auch wenn man den obigen C-Code in C++ ohne Modifikation verwenden kann, möchte man möglicherweise std::string-Instanzen hashen.

hash_sha1_cpp.cpp
/**
 * Hasht einen gegebenen Eingabe-String mit dem SHA1-Algorithmus
 * @param input Zeiger auf die Eingabesequenz
 * @param inputSize Größe der Eingabesequenz
 * @return Ein per new[] reservierter Zeiger auf die resultierenden Daten. 20 Bytes lang.
 */
unsigned char* hashSHA1(const std::string& input) {
    //Initialisierung
    unsigned char* hashResult = new unsigned char[sha1_desc.hashsize];
    //Zustandsvariable für den Hash initialisieren
    hash_state md;
    sha1_init(&md);
    //Text verarbeiten - daran erinnern, dass process() mehrfach aufgerufen werden kann
    sha1_process(&md, (const unsigned char*) input.c_str(), input.size());
    //Hash-Berechnung abschließen
    sha1_done(&md, hashResult);
    // Ergebnis zurückgeben
    return hashResult;
}

Verwendung der Funktionen

In den meisten Fällen möchte man den resultierenden Hash als Hexadezimal-String auf stdout ausgeben. Hier ist ein Beispiel für die Verwendung des C++-Codes.

hash_sha1_use_example.cpp
#include <string>

int main(int argc, char** argv) {
    std::string text = "abcdef";
    unsigned char* hashResult = hashSHA1(text);
    //Als Hex-String auf stdout ausgeben
    for (int x = 0; x < 20; x++) {
        printf("%x", hashResult[x]); //Hex-Format
    }
    printf("\n");
    //Hash-Ergebniszeiger löschen
    delete[] hashResult;
    return 0;
}

Dieser Codeausschnitt gibt 1f8ac1f23c5b5bc1167bda84b833e5c57a77d2 aus.


Check out similar posts by category: C/C++, Cryptography