Merkles Meta-Verfahren

Merkles Meta-Verfahren (auch Merkle-Damgård-Konstruktion) ist eine Methode zur Konstruktion von kryptographischen Hash-Funktionen, die auf Arbeiten von Ralph Merkle und Ivan Damgård zurückgeht.

Gegeben ist eine Kompressionsfunktion f : { 0 , 1 } a + b { 0 , 1 } b {\displaystyle f\colon \{0,1\}^{a+b}\rightarrow \{0,1\}^{b}} , die eine a + b {\displaystyle a+b} Bit lange Eingabe auf eine b {\displaystyle b} Bit lange Ausgabe abbildet. Sie ist kollisionssicher, das heißt, es ist nicht mit realistischem Aufwand möglich, zwei verschiedene Eingaben zu finden, die auf die gleiche Ausgabe abgebildet werden. Durch die Anwendung von Merkles Meta-Verfahren ergibt sich daraus eine kollisionssichere Hash-Funktion h : { 0 , 1 } { 0 , 1 } b {\displaystyle h\colon \{0,1\}^{*}\rightarrow \{0,1\}^{b}} , die beliebig lange Nachrichten auf einen Hashwert von b {\displaystyle b} Bit abbildet.

Vorgehensweise

Aus den Nachrichtenblöcken wird durch wiederholte Anwendung der Kompressionsfunktion der Hashwert erzeugt

Die Nachricht m {\displaystyle m} wird zunächst mit einem Padding-Verfahren zu m ¯ {\displaystyle {\overline {m}}} erweitert, so dass die Länge von m ¯ {\displaystyle {\overline {m}}} ein Vielfaches der Blockgröße a {\displaystyle a} ist. Dann wird m ¯ {\displaystyle {\overline {m}}} in n {\displaystyle n} Blöcke der Länge a {\displaystyle a} aufgeteilt:

m ¯ = m 1 m 2 m n {\displaystyle {\overline {m}}=m_{1}\|m_{2}\|\ldots \|m_{n}} mit | m i | = a {\displaystyle |m_{i}|=a} .

Die Kompressionsfunktion f {\displaystyle f} wird iterativ auf die b {\displaystyle b} Bit lange Ausgabe der vorherigen Iteration und den nächsten Block m i {\displaystyle m_{i}} der erweiterten Nachricht angewandt, bis diese ganz verarbeitet ist. Bei der ersten Iteration besteht die Eingabe aus einem b {\displaystyle b} Bit langen konstanten Initialisierungsvektor H 0 {\displaystyle H_{0}} und dem ersten Nachrichtenblock m 1 {\displaystyle m_{1}} .

H i := f ( H i 1 m i ) ; 1 i n {\displaystyle H_{i}:=f(H_{i-1}\|m_{i});\quad 1\leq i\leq n} .

Der Hash-Wert wird dann aus der letzten Kompressionsausgabe durch eine Finalisierungsfunktion berechnet: h = final ( H n ) {\displaystyle h=\operatorname {final} (H_{n})} . Diese ist häufig die Identität oder eine Trunkierung.

Davies-Meyer-Kompressionsfunktion
Matyas–Meyer–Oseas-Kompressionsfunktion
Miyaguchi-Preneel-Kompressionsfunktion

Die Kompressionsfunktion wird oft aus einer Blockverschlüsselung konstruiert, wofür es hauptsächlich zwei Möglichkeiten gibt. Eine ist die Davies-Meyer-Kompressionsfunktion: H i = E m i ( H i 1 ) H i 1 {\displaystyle H_{i}=E_{m_{i}}(H_{i-1})\oplus H_{i-1}} . Sie nutzt den Nachrichtenblock m i {\displaystyle m_{i}} als Schlüssel, um damit den Verkettungswert H i 1 {\displaystyle H_{i-1}} zu verschlüsseln. Danach wird noch der so berechnete Schlüsseltext mit dem Klartext verknüpft, z. B. durch bitweises XOR. Dadurch wird die Eigenschaft einer Blockchiffre aufgehoben, den Klartext bijektiv auf den Schlüsseltext abzubilden, und die Abbildung von H i 1 {\displaystyle H_{i-1}} auf H i {\displaystyle H_{i}} ähnelt wesentlich mehr einer Zufallsfunktion. Sonst wäre die Kompressionsfunktion auch nicht kollisionssicher, denn ein Angreifer könnte H i {\displaystyle H_{i}} vorgeben und mit verschiedenen m i {\displaystyle m_{i}} entschlüsseln.

Die zweite ist die Matyas–Meyer–Oseas-Kompressionsfunktion: H i = E k i ( m i ) m i {\displaystyle H_{i}=E_{k_{i}}(m_{i})\oplus m_{i}} mit k i = g ( H i 1 ) {\displaystyle k_{i}=g(H_{i-1})} oder k i = H i 1 {\displaystyle k_{i}=H_{i-1}} . Sie verschlüsselt den Nachrichtenblock mit dem Verkettungswert als Schlüssel. Auch hier werden Klar- und Schlüsseltext anschließend verknüpft. Die Funktion g {\displaystyle g} erweitert oder komprimiert H i 1 {\displaystyle H_{i-1}} zur Anpassung an die gegebene Schlüssellänge. Als Modifikation von Matyas–Meyer–Oseas gibt es noch die Miyaguchi-Preneel-Kompressionsfunktion, die sich nur dadurch unterscheidet, dass auch H i 1 {\displaystyle H_{i-1}} mit dem Schlüsseltext verknüpft wird: H i = E k i ( m i ) m i H i 1 {\displaystyle H_{i}=E_{k_{i}}(m_{i})\oplus m_{i}\oplus H_{i-1}} . Das ist vor allem dann von Nutzen, wenn die Funktion g {\displaystyle g} den Verkettungswert komprimieren muss, denn so geht dessen gesamter Informationsgehalt in H i {\displaystyle H_{i}} ein.

Padding

Damit die Kollisionssicherheit der Kompressionsfunktion sich beweisbar auf die Hashfunktion überträgt, muss das Paddingverfahren bestimmte Bedingungen erfüllen. Folgende Bedingungen sind dafür hinreichend:[1]

  • m {\displaystyle m} ist ein Anfangsstück von m ¯ {\displaystyle {\overline {m}}} , d. h., die Nachrichten werden nicht verändert, nur mit einem Endstück erweitert.
  • Zwei Nachrichten der gleichen Länge werden mit gleich langen Endstücken erweitert.
  • Zwei verschieden lange Nachrichten werden unterschiedlich erweitert, so dass sie sich im letzten Block, der in die letzte Kompressionsstufe eingegeben wird, unterscheiden.

Typischerweise wird beim Padden eine Codierung der Bitlänge | m | {\displaystyle \left|m\right|} an die Nachricht angehängt, und dazwischen werden ggfs. Bits mit dem Wert 0 eingefügt, damit | m ¯ | {\displaystyle |{\overline {m}}|} ein Vielfaches der Blockgröße a {\displaystyle a} ist:

m ¯ = m 0 k | m | {\displaystyle {\overline {m}}=m\,\|\,0^{k}\,\|\,|m|}

Schwächen

Eine Schwäche ist ein möglicher Erweiterungs-Angriff (Extension-Attack): Wenn die Finalisierungsfunktion umkehrbar ist, dann kann man aus dem Hashwert h ( m ) {\displaystyle h(m)} einer unbekannten Nachricht m {\displaystyle m} leicht den Hashwert h ( m ¯ y ) {\displaystyle h({\overline {m}}\,\|\,y)} einer Nachricht bestimmen, die aus der wie oben erweiterten Nachricht durch Anfügen einer Erweiterung y {\displaystyle y} hervorgeht. Man kann also Hashwerte zu Nachrichten bestimmen, die m {\displaystyle m} als Anfangsstück haben, auch wenn man m {\displaystyle m} nicht kennt.[2] Da ein Zufallsorakel diese Eigenschaft nicht hat, können sich daraus Angriffe auf Verfahren ergeben, die nur im Random-Oracle-Modell einen Sicherheitsbeweis haben.[3] Daraus folgt auch: wenn man einmal eine Kollision zweier Nachrichten mit gleicher Blockanzahl n {\displaystyle n} gefunden hat, kann man durch Erweiterung leicht weitere Kollisionen bestimmen.

Mehrfachkollisionen zu finden, also mehrere Nachrichten, die alle den gleichen Hashwert haben, erfordert nur wenig mehr Aufwand als das Bestimmen einer einzelnen Kollision.[4]

Ein Herding-Angriff, also zu einem selbst gewählten Hashwert z und einem gegebenen Anfangsstück m {\displaystyle m} einer Nachricht ein passendes Endstück zu finden, so dass die gesamte Nachricht zu z hasht, d. h., ein y {\displaystyle y} mit h ( m y ) = z {\displaystyle h(m\|y)=z} zu finden, erfordert zwar mehr Aufwand als das Finden einer Kollision, aber wesentlich weniger, als es für ein Zufallsorakel als Hashfunktion h {\displaystyle h} der Fall sein sollte.[5]

Ein Angriff zur Bestimmung eines zweiten Urbildes (second preimage attack), bei dem man zu einer gegebenen Nachricht m {\displaystyle m} eine zweite m {\displaystyle m^{\prime }} mit demselben Hashwert h ( m ) = h ( m ) {\displaystyle h(m)=h(m^{\prime })} sucht, ist bei einer Nachricht der Länge von 2 k {\displaystyle 2^{k}} Blöcken mit dem Zeitaufwand k 2 b / 2 + 1 + 2 b k + 1 {\displaystyle k2^{b/2+1}+2^{b-k+1}} möglich, und damit bei langen Nachrichten erheblich schneller als durch systematisches Probieren (brute force), was etwa 2 b {\displaystyle 2^{b}} Schritte erfordert.[6]

Verbesserungen

Zur Überwindung dieser Schwächen hat Stefan Lucks die wide-pipe-hash-Konstruktion vorgeschlagen:[7] Um einen Hashwert von b {\displaystyle b} Bit Länge zu berechnen, verwendet man eine Kompressionsfunktion f {\displaystyle f^{\prime }} , deren Ausgabe länger als b {\displaystyle b} ist, typischerweise doppelt so lang. f {\displaystyle f^{\prime }} komprimiert also 2 b {\displaystyle 2b} Bit aus der vorherigen Iteration und einen a {\displaystyle a} Bit langen Nachrichtenblock zu einer Ausgabe von 2 b {\displaystyle 2b} Bit. Nach der letzten Iteration wird die Ausgabe durch eine weitere Kompressionsfunktion von 2 b {\displaystyle 2b} auf b {\displaystyle b} Bit verkürzt, im einfachsten Fall durch Trunkierung. Beispiele: SHA-512/256, Grøstl.

fast wide pipe hash

Nandi und Paul haben gezeigt, dass diese Konstruktion etwa doppelt so schnell gemacht werden kann (fast wide pipe hash), indem man nur b {\displaystyle b} Bit aus den vorhergehenden Kompressionen in die nächste Kompression eingibt, zusammen mit einem a + b {\displaystyle a+b} Bit langen Nachrichtenblock m i {\displaystyle m_{i}} . Die andere Hälfte der 2 b {\displaystyle 2b} -Kompressionsausgabe wird mit der darauf folgenden Eingabe XOR-verknüpft:[8]

h i = f ( ( Hi ( h i 2 ) Lo ( h i 1 ) ) m i ) ; 1 i n 1 {\displaystyle h_{i}=f^{\prime }\left(\,(\operatorname {Hi} (h_{i-2})\oplus \operatorname {Lo} (h_{i-1}))\;\|\;m_{i}\right);\quad 1\leq i\leq n-1}

In der letzten Stufe wird die Ausgabe der vorletzten komplett verarbeitet, und der Nachrichtenblock m n {\displaystyle m_{n}} ist dafür nur a {\displaystyle a} Bit breit (falls man hier nicht eine andere Kompressionsfunktion mit größerer Eingabe verwendet):

h n = f ( ( Hi ( h n 2 ) Lo ( h n 1 ) ) Hi ( h n 1 ) m n ) {\displaystyle h_{n}=f^{\prime }(\,(\operatorname {Hi} (h_{n-2})\oplus \operatorname {Lo} (h_{n-1}))\;\|\;\operatorname {Hi} (h_{n-1})\;\|\;m_{n})}

Hi ( c ) {\displaystyle \operatorname {Hi} (c)} und Lo ( c ) {\displaystyle \operatorname {Lo} (c)} bedeuten dabei die erste bzw. die zweite Hälfte der Bitkette c {\displaystyle c} .

Neben der wide-pipe-hash-Konstruktion gilt auch die HAIFA-Konstruktion als eine Weiterentwicklung des Merkle-Damgård Verfahrens. Ein Beispiel dafür ist BLAKE.

Einzelnachweise

  1. S. Goldwasser, M. Bellare: Originals vom 20. Mai 2012 auf WebCite)  Info: Der Archivlink wurde automatisch eingesetzt und noch nicht geprüft. Bitte prüfe Original- und Archivlink gemäß Anleitung und entferne dann diesen Hinweis.@1@2Vorlage:Webachiv/IABot/cseweb.ucsd.edu. Summer course on cryptography, MIT, 1996–2001.
  2. Yevgeniy Dodis, Thomas Ristenpart, Thomas Shrimpton: Salvaging Merkle–Damgård for Practical Applications. Preliminary version in Advances in Cryptology - EUROCRYPT '09 Proceedings, Lecture Notes in Computer Science Vol. 5479, A. Joux, ed, Springer-Verlag, 2009, S. 371–388.
  3. J.S. Coron, Y. Dodis, C. Malinaud, P. Puniya: Merkle–Damgård Revisited: How to Construct a Hash Function. Advances in Cryptology – CRYPTO '05 Proceedings, Lecture Notes in Computer Science, Vol. 3621, Springer-Verlag, 2005, S. 21–39.
  4. Antoine Joux: Multicollisions in iterated hash functions. Application to cascaded construction. In: Advances in Cryptology - CRYPTO '04 Proceedings, Lecture Notes in Computer Science, Vol. 3152, M. Franklin, ed, Springer-Verlag, 2004, S. 306–316.
  5. John Kelsey, Tadayoshi Kohno: Herding Hash Functions and the Nostradamus Attack In Eurocrypt 2006, Lecture Notes in Computer Science, Vol. 4004, S. 183–200.
  6. John Kelsey, Bruce Schneier: Second preimages on n-bit hash functions for much less than 2n work. In Ronald Cramer, editor, EUROCRYPT, volume 3494 of LNCS, pages 474–490. Springer, 2005; [1].
  7. S. Lucks: Design Principles for Iterated Hash Functions. In: Cryptology ePrint Archive, Report 2004/253, 2004.
  8. Mridul Nandi, Souradyuti Paul: Speeding Up the Widepipe: Secure and Fast Hashing. In Guang Gong and Kishan Gupta, editor, Indocrypt 2010, Springer, 2010.

Literatur

  • Hans Delfs, Helmut Knebl: Introduction to Cryptography. Springer 2002, ISBN 3-540-42278-1, S. 40.