Ich habe ein Experiment durchgeführt, um genau herauszufinden, wie sich Git in diesem Fall verhalten würde. Dies ist mit Version 2.7.9~rc0+next.20151210 (Debian-Version). Ich habe im Grunde nur die Hash-Größe von 160-Bit auf 4-Bit reduziert, indem ich den folgenden Diff angewendet und Git neu erstellt habe:
--- git-2.7.0~rc0+next.20151210.orig/block-sha1/sha1.c
+++ git-2.7.0~rc0+next.20151210/block-sha1/sha1.c
@@ -246,6 +246,8 @@ void blk_SHA1_Final(unsigned char hashou
blk_SHA1_Update(ctx, padlen, 8);
/* Output hash */
- for (i = 0; i < 5; i++)
- put_be32(hashout + i * 4, ctx->H[i]);
+ for (i = 0; i < 1; i++)
+ put_be32(hashout + i * 4, (ctx->H[i] & 0xf000000));
+ for (i = 1; i < 5; i++)
+ put_be32(hashout + i * 4, 0);
}
Dann habe ich ein paar Übertragungen vorgenommen und folgendes festgestellt.
- Wenn ein Blob mit demselben Hash bereits existiert, erhalten Sie keine Warnungen. Alles scheint in Ordnung zu sein, aber wenn Sie pushen, jemand klont oder Sie zurückkehren, verlieren Sie die neueste Version (im Einklang mit dem, was oben erklärt wird).
- Wenn ein Baumobjekt bereits existiert und Sie einen Blob mit demselben Hash erstellen: Alles wird normal erscheinen, bis Sie entweder versuchen zu pushen oder jemand Ihr Repository klont. Dann werden Sie sehen, dass das Repository beschädigt ist.
- Wenn ein Commit-Objekt bereits existiert und Sie einen Blob mit demselben Hash erstellen: wie bei #2 - beschädigt
- Wenn ein Blob bereits existiert und Sie ein Commit-Objekt mit demselben Hash erstellen, schlägt die Aktualisierung des "ref" fehl.
- Wenn ein Blob bereits existiert und Sie ein Baumobjekt mit demselben Hash erstellen. Die Erstellung der Übergabe wird fehlschlagen.
- Wenn ein Baumobjekt bereits existiert und Sie ein Commit-Objekt mit demselben Hash erstellen, schlägt die Aktualisierung des "ref" fehl.
- Wenn ein Baumobjekt bereits existiert und Sie ein Baumobjekt mit demselben Hash erstellen, scheint alles in Ordnung zu sein. Aber wenn Sie übertragen, wird das gesamte Repository auf den falschen Baum verweisen.
- Wenn ein Commit-Objekt bereits existiert und Sie ein Commit-Objekt mit demselben Hash erstellen, scheint alles in Ordnung zu sein. Aber wenn Sie eine Übergabe machen, wird die Übergabe nie erstellt und der HEAD-Zeiger wird auf eine alte Übergabe verschoben.
- Wenn ein Commit-Objekt bereits existiert und Sie ein Tree-Objekt mit demselben Hash erstellen, schlägt die Erstellung des Commits fehl.
Für #2 erhalten Sie normalerweise eine Fehlermeldung wie diese, wenn Sie "git push" ausführen:
error: object 0400000000000000000000000000000000000000 is a tree, not a blob
fatal: bad blob object
error: failed to push some refs to origin
oder:
error: unable to read sha1 file of file.txt (0400000000000000000000000000000000000000)
wenn Sie die Datei löschen und dann "git checkout file.txt" ausführen.
Für die Nummern 4 und 6 erhalten Sie normalerweise eine Fehlermeldung wie diese:
error: Trying to write non-commit object
f000000000000000000000000000000000000000 to branch refs/heads/master
fatal: cannot update HEAD ref
wenn Sie "git commit" ausführen. In diesem Fall können Sie in der Regel einfach erneut "git commit" eingeben, da dies einen neuen Hash erzeugt (aufgrund des geänderten Zeitstempels)
Für die Nummern 5 und 9 erhalten Sie normalerweise eine Fehlermeldung wie diese:
fatal: 1000000000000000000000000000000000000000 is not a valid 'tree' object
beim Ausführen von "git commit"
Wenn jemand versucht, Ihr beschädigtes Repository zu klonen, wird er in der Regel etwas wie folgt sehen:
git clone (one repo with collided blob,
d000000000000000000000000000000000000000 is commit,
f000000000000000000000000000000000000000 is tree)
Cloning into 'clonedversion'...
done.
error: unable to read sha1 file of s (d000000000000000000000000000000000000000)
error: unable to read sha1 file of tullebukk
(f000000000000000000000000000000000000000)
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry the checkout with 'git checkout -f HEAD'
Was mich "beunruhigt" ist, dass in zwei Fällen (2,3) das Repository ohne Warnungen beschädigt wird, und in drei Fällen (1,7,8) scheint alles in Ordnung zu sein, aber der Inhalt des Repositorys unterscheidet sich von dem, was man erwartet. Leute, die klonen oder ziehen, werden einen anderen Inhalt haben, als Sie ihn haben. Die Fälle 4, 5, 6 und 9 sind in Ordnung, da sie mit einem Fehler abbrechen. Ich denke, es wäre besser, wenn es zumindest in allen Fällen mit einem Fehler abbrechen würde.
89 Stimmen
Einst eine Denksportaufgabe, jetzt potenziell ein tatsächliches Problem .
12 Stimmen
@Toby Diese Frage bezog sich auf eine Vorstellungsangriff was Google demonstriert hat, ist eine Kollisionsangriff -- ähnlich, aber etwas anders. Sie können mehr über den Unterschied lesen aquí .
0 Stimmen
@Saheed Ich verstehe nicht, was an dieser Frage speziell mit einem Angriff vor dem Bild zu tun hat, denn die Frage bezieht sich nur auf a Kollision in einem Git-Repository, nicht um deren Ausnutzung.
4 Stimmen
@Toby Der ursprüngliche Denkanstoß bezog sich nicht auf einen Angriff (weder Vorabbild noch Zusammenstoß), sondern auf einen zufälligen Zusammenstoß, der so unwahrscheinlich ist, dass er nicht in Betracht gezogen werden sollte. Ich denke, Saheed hat zu Recht versucht zu sagen, dass dies noch kein wirkliches Problem ist. Sie haben jedoch Recht, dass der Kollisionsangriff von Google möglicherweise ein Sicherheitsproblem geschaffen hat, je nachdem, wie Git verwendet wird.
2 Stimmen
Hier ist eine zweite Kollision, die nur 320 Byte groß ist privacylog.blogspot.com/2019/12/der-zweite-sha-zusammenstoss.html
2 Stimmen
Mit der Entwicklung eines Angriffs auf das gewählte Präfix für SHA-1 rückt dies in den Bereich des Möglichen. arstechnica.com/information-technology/2020/01/
0 Stimmen
Warum
git
nicht nur das Vorhandensein von SHA-1-Kollusion prüft? Dann wären alle Probleme gelöst.