Hash-Funktionen und SSIS

Vor einiger Zeit habe ich hier einen Beitrag über das Codeplex Projekt SSIS Multiple Hash gemacht. Im damaligen Beitrag ging es mir darum, die Möglichkeiten und verschiedenen Hashfunktionen der Komponente zu erläutern. Warum und wofür die entsprechende Komponente jedoch eingesetzt werden kann oder was Hash-Funktionen überhaupt sind, habe ich damals gewissenhaft ignoriert und möchte ich nun in diesem Beitrag nachholen.

Was sind Hashfunktionen?

Eine Hash-Funktion erstellt aus einer großen Eingabe durch unterschiedliche mathematischen Funktionen und oder Algorithmen eine kleinere Ausgabe, den sogenannten Hashwert, der bei den meisten Algorithmen eine feste Länge aufweist.

Quelle: Wikipedia

Eine Hashfunktion wird im Normalfall bei bereits minimalsten Veränderungen der Eingabe auch eine unterschiedliche Ausgabe erzeugen. Im wesentlichen finden Hash-Funktionen heutzutage 3 verschiedene Einsatzbereiche. Sie werden zum Aufbau von Hashtabellen (vergleich Datenbankindex), als Prüfsumme oder in der Kryptologie verwendet, wobei im Rahmen dieses Artikels die Verwendung als Prüfsumme interessant sein wird. Bekannte Hashfunktionen sind MD5, SHA-1 oder SHA-2.

MD5 ist derzeit der wahrscheinlich am häufigsten eingesetzte Hash-Algorithmus, führt aber auch häufig zu verschiedenen kontroversen Diskussionen bzgl. seiner Sicherheit, wobei vorweg schon einmal erwähnt sei, das an dieser Stelle sehr stark auf den Betrachtungswinkel geachtet werden muss.

Sind Hashwerte unsicher?

Häufig werden Passwörter in Datenbanken nicht im Klartext sondern als Hashwerte abgelegt, da es als unmöglich gilt aus einem Hashwert selber das original Passwort zu generieren. Umgekehrt können jedoch mittels Rainbow Tables oder durch Brute-Force Attacken beliebig viele Kombinationen ausprobiert werden, bis man zu dem entsprechenden Hashwert gelangt. Durch immer schneller werdende Prozessoren, speziell auch bei Grafikkarten oder Spielekonsolen, können heutzutage auf Notebooks bereits bis zu 200 MHash/sec erstellt werden; in einigen Berichten wir häufig vom Einsatz von Cluster-Systemen aus bis zu 200 PlayStations gesprochen.

Bars

Wesentlich interessanter im Bereich der Kryptologie und auch beim Einsatz für Prüfsummen ist die Erzeugung von sogenannten Kollisionen. Hierbei wird versucht eine manipulierte Nachricht zu erzeugen, bei der ein zur Originalnachricht identischer Hashwert durch die jeweils eingesetzte Hashfunktion errechnet wird. So wurde bereits 2008 auf dem Chaos Communication Congress vorgestellt wie ein SSL-CA-Zertifikat durch MD5-Kollisionen geknackt werden konnte.

Grundsätzlich wird beim erzeugen der Kollisionen zwischen einem Kollisionsangriff (oder auch Geburtstagsangriff) und einem Preimage-Angriff unterschieden. Erstere Variante hat zum Ziel zwei Nachrichten zu erzeugen, die einen identischen Hashwert haben, letztere hat zum Ziel, zu einer gegebenen Nachricht ein weitere Nachricht zu finden/erstellen, die den gleichen Hash-Wert erzeugt. Laut Wikipedia ist es einem chinesischem Wissenschaftlerteam gelungen eine Kollisionen für den MD5-Algorithmus in einer Stunde zu erzeugen, weitere Kollisionen ließen sich danach in max. 5 Minuten generieren. Eine Ausführliche Beschreibung dazu findet sich im Artikel “Collisions for Hashfunctions”. Beim SHA-1 sind bisweilen nur theoretische Kollisionen mit großen Aufwand bekannt.

Sind also Hash-Funktionen wie MD5 oder SHA-1 unsicher? It depends…

Um diese Frage zu beantworten, ist – wie oben angesprochen – der Betrachtungswinkel relevant. Aus kryptologischer Sicht kann man die Frage mit einem einfachen Ja beantworten, da verschiedene Hacks im Internet zu finden sind. Viele Kryptologen raten derzeit auch ganz klar von der weiteren Verwendung des MD5 Algorithmus in Anwendungen ab.

Grundsätzlich gilt jedoch, das bei MD5 clip_image002[6] Möglichkeiten existieren, was einer Wahrscheinlichkeit von clip_image002 entspricht. Nur bei gezielten Kollisionsangriffen (Geburtstagsangriffen!) sinkt die Wahrscheinlichkeit je nach Studie auf Werte von clip_image002[8].

 

Warum werden Hashfunktionen innerhalb der Integration Services verwendet?

Innerhalb der SSIS werden Hashfunktionen häufig als Prüfsummen verwendet, um Änderungen zu erkennen. Diese Daten werden dann z.B. mit Hilfe des LookUp-Tasks 1:1 gegen die bereits gespeichert Daten geprüft. Je nach Umfang der zu prüfenden Zeilen, Spalten und Datentypen kann ein 1:1 Vergleich per Lookup-Task extrem lange dauern; speziell beim Vergleich von textbasierten Spalten kann man hier viel Performance einbüßen. Eine gute Beschreibung zum Einsatz von Hash-Werten ist unter anderem in dem Artikel Speeding Up Incremental ETL Processes in SSIS by Using MD5 Hashes zu finden.

Durch den Einsatz von Hash-Algorithmen zur Bildung von Prüfsummen für eine größere Anzahl an Spalten erreicht man, dass nur eine Spalte über den Lookup-Task mit der Zieltabelle verglichen werden muss.

Wie in der Einleitung zu diesem Beitrag angesprochen existiert bei Codeplex eine entsprechende freie Komponente, mit der Hash-Werte über beliebige Eingabespalten gebildet werden können. Möchte man in seinen Paketen keine Komponenten von Drittanbietern einsetzen, so lassen sich entsprechende Hash-Algorithmen über den Script Task auch mit wenigen Zeilen Code einbinden.

 

   1: string TextBuilder = "";

   2:

   3: if (!Row.Freight_IsNull)

   4: {

   5:     TextBuilder += Row.Freight.ToString();

   6: }

   7:

   8: MD5 md5 = new MD5CryptoServiceProvider();

   9: byte[] textToHash = Encoding.Default.GetBytes(TextBuilder.ToString());

  10: byte[] result = md5.ComputeHash(textToHash);

  11:

  12: Row.Hash = System.BitConverter.ToString(result);

 

Wobei die IF-Anweisung für jede zu verwendende Spalte zu setzen ist.

Da der Script-Task als Default das .NET-Framework 2.0 verwendet, stehen einem MD5 und SHA-1 zur Verfügung. Wechselt man das .NET-Framework auf die Version 3.5, stehen einem auch weitere Algorithmen wie SHA-256 zur Verfügung. Auch die Implementierung weiterer Algorithmen wie der FNV Algorithmus lassen sich über den Script-Task leicht implementieren. Eine vollständige Implementierung C# FNV Hash ist auf The Code Project zu finden. Kleine Anmerkung, der entsprechende Code verwendet die C# BigInteger Class, welche ebenfalls auf The Code Project zu finden ist.

Speziell der letzte FNV Algorithmus zeigt aus meiner Sicht, das die häufig geführten Diskussionen über sichere oder unsichere Hash-Algorithmen beim Einsatz innerhalb der Integration Services aneinander vorbeigehen.

Um hier einmal die Wikipedia zu zitieren:

FNV erfüllt alle Kriterien einer guten Hashing-Funktion 
und findet überall breiten Einsatz dort, wo große 
Datenmengen verarbeitet werden sowie Schnelligkeit 
und Zuverlässigkeit gefordert sind [...].
FNV eignet sich jedoch nicht für kryptographischen Einsatz.

Aus Sicht eines ETL-Entwicklers steht nämlich nicht der kryptographische Einsatz im Mittelpunkt, sondern Anforderungen wie Schnelligkeit und Zuverlässigkeit. Zufällige Kollisionen beim generieren von Hash-Werten treten ungefähr so häufig auf, wie doppelt generierte GUID…zumindest rein rechnerisch ;-).