Was ist der Unterschied zwischen einem sicheren Vergleich und einem einfachen == (=)

7

Githubs Sicherung der Webhooks-Seite lautet:

  

Die Verwendung eines einfachen == Operators wird nicht empfohlen. Eine Methode wie secure_compare führt einen Stringvergleich "Konstante Zeit" durch, der sie vor bestimmten Timing-Angriffen gegen reguläre Gleichheitsoperatoren schützt.

Ich benutze bcrypt.compare('string', 'computed hash') beim Vergleich von Passwörtern.

Was macht dies zu einem "sicheren Vergleich" und kann ich dies mithilfe der Standardbibliothek crypto in Node tun?

    
amingilani 28.06.2015, 03:36
quelle

3 Antworten

15

Der Punkt eines "Konstanten Zeit" -Stringvergleichs ist, dass der Vergleich genau die gleiche Zeit benötigt, egal was das Vergleichsziel ist (der unbekannte Wert). Diese "konstante Zeit" zeigt einem Angreifer keine Informationen über den unbekannten Zielwert an. Die übliche Lösung besteht darin, dass alle Zeichen verglichen werden, selbst wenn eine Nichtübereinstimmung gefunden wurde, so dass unabhängig davon, wo eine Nichtübereinstimmung gefunden wird, der Vergleich in der gleichen Zeit abläuft.

Andere Formen des Vergleichs können eine Antwort in einer kürzeren Zeit liefern, wenn bestimmte Bedingungen erfüllt sind, die es einem Angreifer ermöglichen zu erfahren, was ihm möglicherweise fehlt. Zum Beispiel gibt der Vergleich in einem typischen String-Vergleich den Wert false zurück, sobald ein ungleiches Zeichen gefunden wird. Wenn das erste Zeichen nicht übereinstimmt, wird der Vergleich in kürzerer Zeit als in dem Fall zurückgegeben. Ein fleißiger Angreifer kann diese Informationen verwenden, um einen intelligenteren Brute-Force-Angriff durchzuführen.

Ein Vergleich der "konstanten Zeit" eliminiert diese zusätzliche Information, denn egal wie die zwei Strings ungleich sind, die Funktion gibt ihren Wert in der gleichen Zeit zurück.

Wenn ich mir die knotjs v4-Crypto-Bibliothek ansehe, sehe ich keine Anzeichen dafür, dass eine Funktion konstante Zeit benötigt Vergleich und pro dieser Beitrag , gibt es eine Diskussion über die Tatsache, dass die Nodejs Crypto-Bibliothek diese Funktionalität fehlt / p>

BEARBEITEN: Knoten v6 hat jetzt crypto.timingSafeEqual(a, b) .

Es gibt auch eine solche konstante Zeitvergleichsfunktion in diesem Puffer-Gleich-Konstanten-Zeit-Modul .

    
jfriend00 28.06.2015, 04:48
quelle
5

Die Antwort von jfriend ist im Allgemeinen korrekt, aber in Bezug auf diesen spezifischen Kontext (Vergleichen der Ausgabe einer bcrypt-Operation mit dem, was in der Datenbank gespeichert ist) besteht kein Risiko bei der Verwendung von "==".

Denken Sie daran, dass bcrypt eine unidirektionale Funktion ist, die speziell dafür entwickelt wurde, Angriffen durch das Erraten von Kennwörtern zu widerstehen, wenn der Angreifer die Datenbank ergreift. Wenn wir davon ausgehen, dass der Angreifer über die Datenbank verfügt, benötigt der Angreifer keine Timingleck-Informationen, um zu wissen, welches Byte seiner Schätzung für das Passwort falsch ist. Er kann dies selbst überprüfen, indem er einfach auf die Datenbank schaut. Wenn wir davon ausgehen, dass der Angreifer nicht über die Datenbank verfügt, könnten Informationen über das Timingleck uns in einem Szenario, das für den Angreifer ideal ist (das überhaupt nicht realistisch ist), möglicherweise mitteilen, welches Byte falsch war. Selbst wenn er diese Information bekommen könnte, hindert ihn die einseitige Eigenschaft von bcrypt daran, den Wissensgewinn auszunutzen.

Zusammenfassung: Das Verhindern von Timing-Angriffen ist im Allgemeinen eine gute Idee, aber in diesem speziellen Kontext setzen Sie sich nicht in Gefahr, indem Sie "==" verwenden.

BEARBEITEN: Die Funktion bcrypt.compare () funktioniert bereits ist so programmiert, Timing-Attacken zu widerstehen , obwohl es absolut kein Sicherheitsrisiko gibt, dies nicht zu tun.

    
TheGreatContini 28.06.2015 22:22
quelle
2

Stellen Sie sich einen langen Block mit zu vergleichendem Material vor. Wenn der erste Block nicht übereinstimmt und die Vergleichsfunktion dann zurückkehrt, haben Sie Daten an den Angreifer weitergegeben. Er kann an dem ersten Datenblock arbeiten, bis die Routine länger dauert, um zurückzukehren, und zu diesem Zeitpunkt wird er wissen, dass der erste Block übereinstimmt.

2 Möglichkeiten, um Daten zu vergleichen, die sicherer vor Timing-Angriffen sind, sind das Hashing beider Datensätze und das Vergleichen der Hashes oder das XOR aller Daten und das Vergleichen des Ergebnisses mit 0. If == scannt beide Datenblöcke und gibt zurück, wenn und wenn es eine Diskrepanz findet, kann es unabsichtlich "wärmer / kälteres" spielen und den Gegner direkt in den geheimen Text führen, den er zusammenbringen will.

    
WDS 03.08.2015 09:53
quelle

Tags und Links