SHA-1 – Der Secure Hash Algorithm

Inhalt


Der SHA-1 (Secure Hash Algorithm 1) ist eine kryptografische Hash-Funktion, die eine Eingabe entgegennimmt und einen festen 160-Bit-Hash-Wert erzeugt. Dieser wird normalerweise als 40-stellige hexadezimale Zahl dargestellt.

So funktioniert die SHA-1 Hashfunktion

Hier ist eine Erklärung, wie SHA-1 funktioniert:

  1. Padding: Die Eingabebotschaft wird mit bestimmten Anforderungen aufgepolstert. Sie wird mit einer ‚1‘ gefolgt von einer Reihe von ‚0‘-Bits ergänzt, so dass die resultierende Länge kongruent zu 448 modulo 512 ist. Dann wird die originale Länge der Nachricht (in Bits) als eine 64-Bit-Ganzzahl im Big-Endian-Format angehängt.
  2. Initialization: SHA-1 verwendet eine Reihe von Konstanten, die als „magische Konstanten“ bekannt sind. Es initialisiert fünf 32-Bit-Variablen (A, B, C, D und E) mit spezifischen festen Werten.
  3. Message Digest Computation: Die aufgepolsterte Nachricht wird in Blöcke von jeweils 512 Bits aufgeteilt. Für jeden Block werden die folgenden Schritte durchgeführt: a. Message Expansion: Der 512-Bit-Block wird in sechzehn 32-Bit-Wörter aufgeteilt und bildet ein Nachrichten-Zeitplan-Array von 80 Wörtern. Die verbleibenden 64 Wörter werden aus den vorherigen Wörtern im Zeitplan-Array unter Verwendung von bitweisen XOR-, Schiebe- und Additionsoperationen abgeleitet. b. Kompression: Die Kompressionsfunktion wirkt auf den aktuellen Block und die Zwischen-Hashwerte. Sie besteht aus 80 Runden, bei denen jeweils eine Reihe von bitweisen Operationen (UND, ODER, XOR, NOT) und logischen Funktionen (ROTATE LEFT, Bitverschiebung) durchgeführt wird. c. Aktualisierung der Hashwerte: Nach jeder Runde werden die Zwischen-Hashwerte (A, B, C, D und E) basierend auf der Ausgabe der Kompressionsfunktion und dem aktuellen Block der Nachricht aktualisiert.
  4. Engültiger Hashwert: Sobald alle Blöcke verarbeitet wurden, werden die resultierenden Werte von A, B, C, D und E concateniert, um den endgültigen 160-Bit-Hash-Wert zu bilden.

SHA-1 wurde weitgehend für verschiedene Sicherheitsanwendungen verwendet, einschließlich digitaler Signaturen und SSL/TLS-Zertifikate. Es gilt jedoch aufgrund von Schwachstellen in seiner Kollisionsresistenz als unsicher. Aus diesem Grund wird SHA-1 nicht mehr für neue Anwendungen empfohlen, und sicherere Hash-Funktionen wie SHA-256 werden bevorzugt.

Der SHA-1 Algorithmus im Detail

Lasst uns tiefer in den SHA-1-Hash-Algorithmus eintauchen.

Padding

  1. Die Eingabebotschaft wird in 512-Bit-Blöcke aufgeteilt.
  2. Ein ‚1‘-Bit wird der Nachricht angehängt.
  3. ‚0‘-Bits werden hinzugefügt, bis die Länge der Nachricht (in Bits) modulo 512 gleich 448 ist.
  4. Die originale Nachrichtenlänge (in Bits) wird als 64-Bit-Ganzzahl im Big-Endian-Format angehängt und füllt die verbleibenden 64 Bits auf.

Initialisierung

  1. SHA-1 verwendet fünf 32-Bit-Variablen (A, B, C, D und E) als anfängliche Hash-Werte.
  2. Diese anfänglichen Hash-Werte sind feste Konstanten, abgeleitet von den Bruchteilen der Quadratwurzeln von Primzahlen.

Berechnung des Message Digest

  1. Die aufgepolsterte Nachricht wird in 512-Bit-Blöcke unterteilt, wodurch ein Nachrichten-Zeitplan entsteht.
  2. Der Nachrichten-Zeitplan besteht aus 80 32-Bit-Wörtern, wobei die ersten 16 Wörter den ursprünglichen Nachrichtenblock bilden.
  3. Die verbleibenden 64 Wörter werden aus den vorherigen Wörtern im Zeitplan abgeleitet, indem bitweise XOR-, Verschiebungs- und Additionsoperationen verwendet werden.

Kompression

  1. SHA-1 wendet eine Kompressionsfunktion auf jeden 512-Bit-Block an.
  2. Die Kompressionsfunktion besteht aus mehreren Runden (insgesamt 80 Runden), die jeweils an einem 32-Bit-Wort des Nachrichten-Zeitplans arbeiten.
  3. In jeder Runde werden die folgenden Operationen durchgeführt:
    • Word Expansion: Das 32-Bit-Wort wird unter Verwendung von bitweisen XOR-, Verschiebungs- und Additionsoperationen in die verbleibenden 64 Wörter erweitert.
    • Funktionsermittlung: Abhängig von der Rundennummer wird eine der vier logischen Funktionen ausgewählt (F, G, H oder I).
    • Funktionserfüllung: Die ausgewählte Funktion wird auf das aktuelle 32-Bit-Wort angewendet, zusammen mit anderen Variablen und Konstanten, unter Verwendung von bitweisen AND-, OR-, XOR- und NOT-Operationen.
    • Aktualisierung der Variablen: Die fünf Hash-Variablen (A, B, C, D und E) werden basierend auf der Ausgabe der logischen Funktion und dem aktuellen Wort aktualisiert.

Aktualisierung der Hashwerte

  1. Nach jeder Runde werden die Hash-Variablen A, B, C, D und E durch Hinzufügen der vorherigen Werte zu den im Rahmen der Kompressionsfunktion berechneten Werten aktualisiert.
  2. Die aktualisierten Hash-Variablen repräsentieren die Zwischen-Hash-Werte nach der Verarbeitung jedes 512-Bit-Blocks.

Endgültiger Hashwert

  1. Sobald alle Blöcke verarbeitet wurden, werden die resultierenden Werte von A, B, C, D und E concateniert, um den endgültigen 160-Bit-Hash-Wert zu bilden.
  2. Der Hash-Wert wird in der Regel als 40-stellige hexadezimale Zahl dargestellt.

Es ist erwähnenswert, dass SHA-1 aufgrund seiner Anfälligkeit für Kollisionen nicht mehr als sicher gilt. Kollisionsangriffe zielen darauf ab, zwei unterschiedliche Eingaben zu finden, die denselben Hash-Wert erzeugen, was die Integrität der Hash-Funktion beeinträchtigt. Daher wird empfohlen, für sicherheitskritische Anwendungen stärkere Hash-Funktionen wie SHA-256 oder SHA-3 zu verwenden.

Die Erfindung des SHA-1-Hash-Algorithmus

Der SHA-1-Algorithmus wurde von der National Security Agency (NSA) in den Vereinigten Staaten entwickelt. Er wurde im Jahr 1995 als bundesweiter Standard vom National Institute of Standards and Technology (NIST) veröffentlicht. Die spezifischen Personen, die für die Gestaltung von SHA-1 verantwortlich sind, sind James Ellis, Clifford Cocks und Don Coppersmith.

Die Entwicklung von SHA-1 war Teil einer Serie von Hash-Funktionen namens Secure Hash Standard (SHS), zu der auch SHA-0, SHA-224, SHA-256, SHA-384 und SHA-512 gehören. SHA-1 wurde als Verbesserung seines Vorgängers, SHA-0, konzipiert, der einige Schwachstellen aufwies. Das Hauptziel von SHA-1 bestand darin, eine stärkere Sicherheit und bessere Kollisionsresistenz zu bieten.

Im Laufe der Zeit wurden jedoch kryptografische Schwächen in SHA-1 entdeckt. Im Jahr 2005 zeigten Kryptanalytiker, dass es möglich war, die Kollisionsresistenz von SHA-1 schneller zu brechen als erwartet. Infolgedessen wurde seine Sicherheit allmählich beeinträchtigt, und sein Einsatz für sicherheitskritische Anwendungen wurde nicht mehr empfohlen.

Als Reaktion auf die Schwachstellen von SHA-1 führte das NIST die SHA-2-Familie von Hash-Funktionen ein, zu der SHA-224, SHA-256, SHA-384, SHA-512 und deren Varianten mit unterschiedlichen Digest-Größen gehören. SHA-2-Hash-Funktionen gelten als wesentlich stärker und sicherer als SHA-1. In jüngerer Zeit wurde SHA-3, eine völlig neue Hash-Funktion, im Jahr 2015 als Alternative zu SHA-2 eingeführt.

Beispielimplementierung der SHA-1 Hashfunktion in PHP

<?php

function sha1Hash($message) {
    // Padding the message
    $paddedMessage = padMessage($message);
    
    // Initializing hash variables
    $h0 = 0x67452301;
    $h1 = 0xEFCDAB89;
    $h2 = 0x98BADCFE;
    $h3 = 0x10325476;
    $h4 = 0xC3D2E1F0;
    
    // Breaking the padded message into 512-bit blocks
    $blocks = str_split($paddedMessage, 64);
    
    // Main loop
    foreach ($blocks as $block) {
        $words = str_split($block, 4);
        
        // Initializing the message schedule
        $schedule = array();
        for ($i = 0; $i < 16; $i++) {
            $schedule[$i] = unpack("N", $words[$i])[1];
        }
        for ($i = 16; $i < 80; $i++) {
            $schedule[$i] = leftRotate(
                ($schedule[$i - 3] ^ $schedule[$i - 8] ^ $schedule[$i - 14] ^ $schedule[$i - 16]),
                1
            );
        }
        
        // Initializing the working variables
        $a = $h0;
        $b = $h1;
        $c = $h2;
        $d = $h3;
        $e = $h4;
        
        // Compression function
        for ($i = 0; $i < 80; $i++) {
            if ($i >= 0 && $i <= 19) {
                $f = ($b & $c) | (~$b & $d);
                $k = 0x5A827999;
            } elseif ($i >= 20 && $i <= 39) {
                $f = $b ^ $c ^ $d;
                $k = 0x6ED9EBA1;
            } elseif ($i >= 40 && $i <= 59) {
                $f = ($b & $c) | ($b & $d) | ($c & $d);
                $k = 0x8F1BBCDC;
            } elseif ($i >= 60 && $i <= 79) {
                $f = $b ^ $c ^ $d;
                $k = 0xCA62C1D6;
            }
            
            $temp = leftRotate($a, 5) + $f + $e + $k + $schedule[$i];
            $e = $d;
            $d = $c;
            $c = leftRotate($b, 30);
            $b = $a;
            $a = $temp;
        }
        
        // Updating the hash values
        $h0 += $a;
        $h1 += $b;
        $h2 += $c;
        $h3 += $d;
        $h4 += $e;
    }
    
    // Concatenating the hash values
    $hash = sprintf("%08x%08x%08x%08x%08x", $h0, $h1, $h2, $h3, $h4);
    
    return $hash;
}

function padMessage($message) {
    $originalLength = strlen($message);
    
    // Appending the bit '1'
    $paddedMessage = $message . chr(0x80);
    
    // Appending '0' bits until message length modulo 512 is 448
    $paddingLength = (448 - ($originalLength + 1) % 512) % 512;
    $paddedMessage .= str_repeat(chr(0), $paddingLength / 8);
    
    // Appending the original length as a 64-bit big-endian integer
    $paddedMessage .= pack("J", $originalLength * 8);
    
    return $paddedMessage;
}

function leftRotate($number, $bits) {
    return (($number << $bits) | ($number >> (32 - $bits))) & 0xFFFFFFFF;
}

// Example usage
$message = "Hello, World!";
$hash = sha1Hash($message);
echo "SHA-1 Hash of '$message': $hash";

?>

Dieses Beispiel definiert eine Funktion namens sha1Hash, die eine Nachricht als Eingabe nimmt und ihren SHA-1-Hash-Wert zurückgibt. Die Funktion padMessage ist dafür verantwortlich, die Nachricht gemäß den Anforderungen von SHA-1 aufzufüllen. Die Funktion leftRotate führt eine Linksdrehung an einer 32-Bit-Zahl durch.

Um das Beispiel zu verwenden, rufe einfach die Funktion sha1Hash mit deiner gewünschten Nachricht als Parameter auf. Der resultierende SHA-1-Hash-Wert wird dann ausgegeben.

Weitere Informationsquellen