Da jeder ständig bewusst und unbewusst Hash-Algorithmen benutzt schreibe ich hier ein kleines Tutorial darüber,wie Hash-Algorithmen grundlegend funktionieren und wie man seinen eigenen kleinen Hash-Algorithmus in C implementiert.
Informationen über Hashing-Verfahren und Hash-Algorithmen findet ihr hier:
-> http://de.wikipedia.org/wiki/Hashfunktion
-> http://de.wikipedia.org/wiki/Kryptologische_Hashfunktion
-> http://de.wikipedia.org/wiki/Md5
-> http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
Zunächst einmal: Was ist ein Hash-Algorithmus bzw. eine Hashfunktion eigentlich ?
Hash-Algorithmen werden hauptsächlich benutzt um die Integrität einer Datei zu überprüfen, für digitale Signaturen (Danke an Johannes) oder um Passwörter in Datenbanken zu speichern.
Ziel des Hashens von Daten ist es, dass man zum einen bei einer minimalen Veränderung in der Datei eine starke Veränderung der Hashsumme erhält und zum anderen, dass Hashfunktionen so gebaut sind (sein sollten), dass sie sich (jedenfalls in Polynomialzeit) nicht umkehren lassen. Es ist also nicht möglich, von einer gegebenen Hashsumme wieder auf die Ursprungsdaten zurückzukommen.
edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb
Das ist die SHA256 Hashsumme des Textes „abc“.
Ändert man nun den Text auch nur um einen Buchstaben z.B. „abb“ so erhält man eine vollständig andere Hashsumme :
3fe1a3938782c0fb2bf47746f2ba9e5a56ecab2afc57589b4cc97713e00b3bb4
Was passiert mit Daten, wenn sie einen Hash-Algorithmus durchlaufen ?
Die Tatsache, dass sich ein Hash-Algorithmus praktisch nicht umkehren lässt mag für den ein oder anderen vielleicht ersteinmal verwirrend klingen. Aber man kann dies an einem kleinen Beispiel zeigen:
Als Beispiel für Daten nehmen wir die Zahl 1234. Was kann man mit dieser Zahl nun mathematisch anstellen um ein Ergeniss zu erhalten, aus welchem sich die Ursprungszahl nicht zurückberechnen lässt ?
Wir nehmen einfach die die Quersumme. Die Quersumme von 1234 ist 10.
Aus diesem Ergebnis lässt sich nun nichtmehr eindeutig zurückrechen, dass wir mit 1234 angefangen haben. Es könnte genauso gut 11134 gewesen sein oder 4321.
Implementierung eines kleinen Hash-Algorithmus in C
Als nächstes werde ich zeigen, wie man einen kleinen Hash-Algorithmus in C implementiert.
Dass der hier gezeigt Algorithmus natürlich nicht wirklich zu gebrauchen ist sollte klar sein.
Die gängigen Hash-Algorithmen wie SHA und MD5 existieren seit Jahren und wurden von vielen Mathematikern durchdacht.
Daher dient dieser nur als Beispiel.
Einfach mit z.B. gcc kompilieren.
Syntax: ./[Binärdatei] [Datei zum Hashen]
#include <stdlib.h>int hash(char *arg) {
int result = 1;
int modulo = 100043;
FILE *file;
file = fopen(arg, „r“);
if (file != NULL) {
int a = fgetc(file);
int b;
while ( a != EOF ) {
//printf(„%i\n“, result);
b = fgetc(file);
if ( b != EOF ) {
result = ( ( result * a ) + b ) % modulo;
} else if ( b == EOF ) {
result = (result * a) % modulo;
}
a = fgetc(file);
}
} else {
printf(„No File\n“);
}
return result;
}void main (int count, char **args) {
int out = hash(args[1]);
printf(„%i\n“, out);
}
Die Datei wird eingelesen und dann Byte für Byte „verschlüsselt“ (gehasht), wobei am Ende jeder Iteration modulo mit einer Primzahl gerechnet wird um die Länge des Hashs zu einzugrenzen.
Ich werde jetzt nicht den Code Zeile für Zeile erklären, da er relativ selbsterklärend ist.
Ich hoffe ich konnte dem einen oder anderen einen kleinen Einblick in das Thema Hashing geben.
Falls fragen zu dem Code auftauchen einfach PN an mich oder hier in den Thread schreiben.
Edit: Durch das Auskommentieren folgender Zeile im Code lassen sich die Zwischenergebnisse mitverfolgen.
//printf("%i\n", result);