Ich habe darüber gelesen, dass Git SHA-1 Digest als ID für eine Revision verwendet. Warum wird keine modernere Version von SHA verwendet?
Ich habe darüber gelesen, dass Git SHA-1 Digest als ID für eine Revision verwendet. Warum wird keine modernere Version von SHA verwendet?
Antworten:
Warum wird keine modernere Version von SHA verwendet?
Dezember 2017: Es wird. Und Git 2.16 (Q1 2018) ist die erste Version, die diese Absicht veranschaulicht und implementiert.
Hinweis: siehe Git 2.19 unten: Es wird SHA-256 sein .
Git 2.16 wird eine Infrastruktur vorschlagen, um zu definieren, welche Hash-Funktion in Git verwendet wird, und sich bemühen, diese in verschiedenen Codepfaden auszuloten.
Siehe Commit c250e02 (28. November 2017) von Ramsay Jones (``) .
Siehe Commit eb0ccfd , Commit 78a6766 , Commit f50e766 , Commit abade65 (12. November 2017) von Brian M. Carlson ( bk2204
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 721cc43 , 13. Dezember 2017)
Struktur hinzufügen, die den Hash-Algorithmus darstellt
Da wir in Zukunft einen zusätzlichen Hash-Algorithmus unterstützen möchten, fügen Sie eine Struktur hinzu, die einen Hash-Algorithmus und alle dazugehörigen Daten darstellt .
Fügen Sie eine Konstante hinzu, um eine einfache Aufzählung von Hash-Algorithmen zu ermöglichen .
Implementieren Sie eine Funktiontypedefs
zum Erstellen einer abstrakten API, die von jedem Hash-Algorithmus verwendet werden kann, sowie Wrapper für die vorhandenen SHA1-Funktionen, die dieser API entsprechen.Legen Sie einen Wert für die Hex-Größe sowie die Binärgröße fest .
Während einer immer doppelt so groß ist wie der andere, werden beide Werte in der gesamten Codebasis sehr häufig verwendet und führen beide zu einer verbesserten Lesbarkeit.Fügen Sie keinen Eintrag in die Hash-Algorithmus-Struktur für die Null-Objekt-ID ein.
Da es sich bei diesem Wert ausschließlich um Nullen handelt, kann jede Objekt-ID mit geeigneter Größe und Null verwendet werden, und es ist nicht erforderlich, eine bestimmte Eins pro Hash zu speichern.Der aktuelle Plan für den Übergang von Hash-Funktionen sieht einen Zeitpunkt vor, zu dem Eingaben des Benutzers akzeptiert werden, die möglicherweise im SHA-1-Format oder im NewHash-Format vorliegen.
Da wir nicht wissen können, was der Benutzer angegeben hat, fügen Sie eine Konstante hinzu, die den unbekannten Algorithmus darstellt , damit wir angeben können, dass wir den richtigen Wert nachschlagen müssen.
Integrieren Sie die Unterstützung von Hash-Algorithmen in das Repo-Setup
In zukünftigen Versionen von Git planen wir, einen zusätzlichen Hash-Algorithmus zu unterstützen.
Integrieren Sie die Aufzählung von Hash-Algorithmen in das Repository-Setup und speichern Sie einen Zeiger auf die aufgezählten Daten im Struktur-Repository .
Natürlich unterstützen wir derzeit nur SHA-1, also codieren Sie diesen Wert fest inread_repository_format
.
In Zukunft werden wir diesen Wert aus der Konfiguration auflisten.Fügen Sie eine Konstante hinzu,
the_hash_algo
die auf denhash_algo
Strukturzeiger im globalen Repository zeigt.
Beachten Sie, dass dies der Hash ist, mit dem Daten auf die Festplatte serialisiert werden, und nicht der Hash, mit dem dem Benutzer Elemente angezeigt werden.
Der Übergangsplan sieht vor, dass diese unterschiedlich sein können.
Wir können in Zukunft ein zusätzliches Element hinzufügen (z. B.ui_hash_algo
), um diesen Fall zu berücksichtigen.
Update August 2018, für Git 2.19 (Q3 2018) scheint Git SHA-256 als NewHash zu wählen.
Siehe Commit 0ed8d8d (04. August 2018) von Jonathan Nieder ( artagnon
) .
Siehe Commit 13f5e09 (25. Juli 2018) von Ævar Arnfjörð Bjarmason ( avar
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 34f2297 , 20. August 2018)
doc
hash-function-transition
: Wählen Sie SHA-256 als NewHashAus Sicherheitsgründen scheint es, dass SHA-256, BLAKE2, SHA3-256, K12 usw. ähnliche Sicherheitseigenschaften aufweisen.
Alle sind aus Sicherheitsgründen gute Optionen.SHA-256 bietet eine Reihe von Vorteilen:
Es gibt es schon seit einiger Zeit, es ist weit verbreitet und wird von nahezu jeder einzelnen Kryptobibliothek (OpenSSL, mbedTLS, CryptoNG, SecureTransport usw.) unterstützt.
Im Vergleich zu SHA1DC sind die meisten vektorisierten SHA-256-Implementierungen sogar ohne Beschleunigung schneller.
Wenn wir Signaturen mit OpenPGP (oder sogar mit CMS) erstellen, werden wir SHA-2 verwenden. Daher ist es nicht sinnvoll, dass unsere Sicherheit von zwei separaten Algorithmen abhängt, wenn einer von beiden allein könnte die Sicherheit brechen, wenn wir uns nur auf eine verlassen könnten.
Also SHA-256 ist es .
Aktualisieren Sie das Designdokument für den Hash-Funktionsübergang, um dies zu sagen.Nach diesem Patch gibt es keine verbleibenden Instanzen der Zeichenfolge "
NewHash
", außer einer nicht verwandten Verwendung aus dem Jahr 2008 als Variablenname int/t9700/test.pl
.
Sie können diesen Übergang zu SHA 256 mit Git 2.20 (Q4 2018) sehen:
Sehen Sie verpflichten 0d7c419 , begehen dda6346 , begehen eccb5a5 , begehen 93eb00f , begehen d8a3a69 , begehen fbd0e37 , begehen f690b6b , begehen 49d1660 , begehen 268babd , begehen fa13080 , begehen 7b5e614 , begehen 58ce21b , begehen 2f0c9e9 , begehen 825544a (15. Oktober 2018) von brian m . Carlson ( bk2204
) .
Siehe Commit 6afedba (15. Oktober 2018) von SZEDER Gábor ( szeder
) .
(Zusammengeführt vonJunio C Hamano - gitster
- in Commit d829d49 , 30. Oktober 2018)
Ersetzen Sie fest codierte Konstanten
Ersetzen Sie mehrere 40-basierte Konstanten durch Verweise auf
GIT_MAX_HEXSZ
oderthe_hash_algo
, falls zutreffend.
Konvertieren Sie alle Verwendungen vonGIT_SHA1_HEXSZ
tothe_hash_algo
so, dass sie für eine bestimmte Hash-Länge geeignet sind.
Anstatt eine fest codierte Konstante für die Größe einer Hex-Objekt-ID zu verwenden, wechseln Sie, um den berechneten Zeiger vonparse_oid_hex
diesen Punkten nach der analysierten Objekt-ID zu verwenden.
GIT_SHA1_HEXSZ
wird weiter entfernt / durch Git 2.22 (Q2 2019) ersetzt und d4e568b festgeschrieben .
Dieser Übergang wird mit Git 2.21 (Q1 2019) fortgesetzt, das sha-256-Hash hinzufügt und durch den Code steckt, um das Erstellen von Git mit dem "NewHash" zu ermöglichen.
Sehen Sie verpflichten 4b4e291 , begehen 27dc04c , begehen 13eeedb , begehen c166599 , begehen 37649b7 , begehen a2ce0a7 , begehen 50c817e , begehen 9a3a0ff , begehen 0dab712 , begehen 47edb64 (14. November 2018) und begehen 2f90b9d , begehen 1ccf07c (22. Oktober 2018) von brian m . Carlson ( bk2204
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 33e4ae9 , 29. Januar 2019)
Hinzufügen einer Basisimplementierung der SHA-256-Unterstützung (Februar 2019)
SHA-1 ist schwach und wir müssen zu einer neuen Hash-Funktion übergehen.
Seit einiger Zeit bezeichnen wir diese neue Funktion alsNewHash
.
Vor kurzem haben wir uns für SHA-256 als entschiedenNewHash
.
Die Gründe für die Wahl von SHA-256 werden in diesem Thread und im Commit-Verlauf für das Hash-Funktionsübergangsdokument beschrieben.Fügen Sie eine grundlegende Implementierung von SHA-256 basierend auf off hinzu
libtomcrypt
, die gemeinfrei ist.
Optimieren Sie es und strukturieren Sie es neu, um unsere Codierungsstandards zu erfüllen.
Ziehen Sie die Update- und Final-Funktionen aus der SHA-1-Block-Implementierung, da wir diese Funktion bei allen Compilern korrekt kennen. Diese Implementierung ist langsamer als SHA-1, aber in zukünftigen Commits werden leistungsfähigere Implementierungen eingeführt.Verbinden Sie SHA-256 in der Liste der Hash-Algorithmen und fügen Sie einen Test hinzu, dass der Algorithmus ordnungsgemäß funktioniert.
Beachten Sie, dass es mit diesem Patch immer noch nicht möglich ist, in Git auf SHA-256 umzusteigen.
Zusätzliche Patches sind erforderlich, um den Code für einen größeren Hash-Algorithmus vorzubereiten, und weitere Testkorrekturen sind erforderlich.
hash
: Fügen Sie eine SHA-256-Implementierung mit OpenSSL hinzuWir haben bereits OpenSSL-Routinen für SHA-1 verfügbar, fügen Sie also auch Routinen für SHA-256 hinzu.
Auf einem Core i7-6600U ist diese SHA-256-Implementierung im Vergleich zur SHA1DC-SHA-1-Implementierung günstig:
SHA-1: 157 MiB/s (64 byte chunks); 337 MiB/s (16 KiB chunks) SHA-256: 165 MiB/s (64 byte chunks); 408 MiB/s (16 KiB chunks)
sha256
: Fügen Sie eine SHA-256-Implementierung mit hinzulibgcrypt
Im Allgemeinen erzielen kryptografische Routinen, die in Assembly geschrieben wurden, eine bessere Leistung als C, und dies gilt auch für SHA-256.
Darüber hinaus können die meisten Linux-Distributionen Git aus Lizenzgründen nicht mit OpenSSL verknüpfen.Die meisten Systeme mit GnuPG haben auch
libgcrypt
, da es eine Abhängigkeit von GnuPG ist.
libgcrypt
ist auch schneller als die SHA1DC-Implementierung für Nachrichten mit einigen KiB und mehr.Zum Vergleich: Auf einem Core i7-6600U verarbeitet diese Implementierung 16 KiB-Chunks mit 355 MiB / s, während SHA1DC äquivalente Chunks mit 337 MiB / s verarbeitet.
Darüber hinaus ist libgcrypt unter der LGPL 2.1 lizenziert, die mit der GPL kompatibel ist. Fügen Sie eine Implementierung von SHA-256 hinzu, die libgcrypt verwendet.
Die Upgrade-Bemühungen werden mit Git 2.24 (Q4 2019) fortgesetzt.
Sehen Sie verpflichten aaa95df , begehen be8e172 , begehen 3f34d70 , begehen fc06be3 , begehen 69fa337 , begehen 3a4d7aa , begehen e0cb7cd , begehen 8d4d86b , begehen f6ca67d , begehen dd336a5 , begehen 894c0f6 , begehen 4439c7a , begehen 95518fa , begehen e84f357 , begehen fe9fec4 , begehen 976ff7e , verpflichten 703d2d4 , Commit 9d958cc , Commit 7962e04 , Commit Fee4930(18. August 2019) von brian m. Carlson ( bk2204
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 676278f , 11. Oktober 2019)
Wechseln Sie zu "Verwenden", anstatt
GIT_SHA1_HEXSZ
Konstanten zu verwenden und fest zu codierenthe_hash_algo
.
Mit Git 2.26 (Q1 2020) sind die Testskripte für den Tag bereit, an dem die Objektnamen SHA-256 verwenden.
Sehen Sie verpflichten 277eb5a , begehen 44b6c05 , begehen 7a868c5 , begehen 1b8f39f , begehen a8c17e3 , begehen 8.320.722 , begehen 74ad99b , begehen ba1be1a , begehen cba472d , begehen 82d5aeb , begehen 3c5e65c , begehen 235d3cd , begehen 1d86c8f , begehen 525a7f1 , begehen 7a1bcb2 , begehen cb78f4f , verpflichten 717c939 , Commit 08a9dd8 , Commit 215b60b , Commit 194264c(21. Dezember 2019) von brian m. Carlson ( bk2204
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit f52ab33 , 05. Februar 2020)
Beispiel:
t4204
: Hash-Größe unabhängig machenUnterzeichnet von: brian m. Carlson
Verwenden Sie
$OID_REGEX
anstelle eines fest codierten regulären Ausdrucks.
Also, anstatt zu verwenden:
grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
Tests verwenden
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
Und OID_REGEX
kommt von commit bdee9cd (13. Mai 2018) von brian m. Carlson ( bk2204
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 9472b13 , 30. Mai 2018, Git v2.18.0-rc0)
t/test-lib
: vorstellenOID_REGEX
Unterzeichnet von: brian m. Carlson
Derzeit haben wir eine Variable,
$_x40,
die einen regulären Ausdruck enthält, der einer vollständigen Hex-Konstante mit 40 Zeichen entspricht.Mit haben
NewHash
wir jedoch Objekt-IDs, die länger als 40 Zeichen sind.In einem solchen Fall
$_x40
wird ein verwirrender Name sein.Erstellen Sie eine
$OID_REGEX
Variable, die unabhängig von der Länge des aktuellen Hashs immer einen regulären Ausdruck widerspiegelt, der mit der entsprechenden Objekt-ID übereinstimmt.
Und noch für Tests:
Sehen Sie verpflichten f303765 , begehen edf0424 , begehen 5db24dc , begehen d341e08 , begehen 88ed241 , begehen 48c10cc , begehen f7ae8e6 , begehen e70649b , begehen a30f93b , begehen a79eec2 , begehen 796d138 , begehen 417e45e , begehen dfa5f53 , begehen f743e8f , begehen 72f936b , begehen 5df0f11 , verpflichten 07877f3 , Commit 6025e89 , Commit 7b1a182 , Commit 94db7e3 ,Commit db12505 (07. Februar 2020) von Brian M. Carlson ( bk2204
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 5af345a , 17. Februar 2020)
t5703
: Test mit SHA-256 arbeiten lassenUnterzeichnet von: brian m. Carlson
Bei diesem Test wurde eine Objekt-ID mit einer Länge von 40 Hex-Zeichen verwendet, wodurch der Test nicht nur nicht bestanden, sondern auch hängen blieb, wenn er mit SHA-256 als Hash ausgeführt wurde.
Ändern diesen Wert auf eine feste Dummy - Objekt - ID verwendet
test_oid_init
undtest_oid
.Stellen Sie außerdem sicher, dass wir eine Objekt-ID mit der entsprechenden Länge extrahieren, indem Sie anstelle einer festen Länge mit Feldern schneiden.
Einige Codepfade erhielten eine Repository-Instanz als Parameter für die Arbeit im Repository, übergaben jedoch die the_repository
Instanz an ihre Callees, die mit Git 2.26 (Q1 2020) (etwas) bereinigt wurde.
Siehe Commit b98d188 , Commit 2dcde20 , Commit 7ad5c44 , Commit c8123e7 , Commit 5ec9b8a , Commit a651946 , Commit eb999b3 (30. Januar 2020) von Matheus Tavares ( matheustavares
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 78e67cd , 14. Februar 2020)
sha1-file
: Erlaubecheck_object_signature()
, mit jedem Repo umzugehenUnterzeichnet von: Matheus Tavares
Einige Aufrufer von
check_object_signature()
können an beliebigen Repositorys arbeiten, aber das Repo wird nicht an diese Funktion übergeben. Stattdessenthe_repository
wird immer intern verwendet.
Um mögliche Inkonsistenzen zu beheben, lassen Sie die Funktion ein Struktur-Repository empfangen und veranlassen Sie diese Aufrufer, das zu behandelnde Repo weiterzuleiten.
Beyogen auf:
sha1-file
: weitergebengit_hash_algo
anhash_object_file()
Unterzeichnet von: Matheus Tavares
Ermöglichen Sie
hash_object_file()
die Arbeit an beliebigen Repos, indem Sie einengit_hash_algo
Parameter einführen . Ändern Sie Aufrufer, die einen Struktur-Repository-Zeiger in ihrem Bereich haben, so, dass sie dasgit_hash_algo
aus dem Repo weiterleiten.
Geben Sie für alle anderen Anrufer weiterthe_hash_algo
, die bereits intern bei verwendet wurdenhash_object_file()
.
Diese Funktionalität wird im folgenden Patch verwendet, umcheck_object_signature()
die Arbeit an beliebigen Repos zu ermöglichen (die wiederum verwendet werden, um eine Inkonsistenz unterobject.c
: parse_object () zu beheben ).
git rev-parse
kann jetzt drucken, welcher Hash verwendet wird: stackoverflow.com/a/58862319/6309 . Und der leere Baum hat eine neue SHA2-ID: stackoverflow.com/a/9766506/6309
UPDATE : Die obige Frage und diese Antwort stammen aus dem Jahr 2015. Seitdem hat Google die erste SHA-1-Kollision angekündigt: https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
Natürlich kann ich nur von außen darüber spekulieren, warum Git weiterhin SHA-1 verwendet, aber dies kann einer der Gründe sein:
unsigned char[20]
Puffer überall vor ;-), es ist viel einfacher, die kryptografische Agilität zu Beginn zu programmieren, als sie später nachzurüsten.Einige Links:
Meine persönliche Ansicht wäre, dass, während praktische Angriffe wahrscheinlich eine Auszeit haben und selbst wenn sie auftreten, die Leute sie wahrscheinlich zunächst mit anderen Mitteln als der Änderung des Hash-Algorithmus selbst abschwächen werden, dass Sie sich irren sollten, wenn Sie sich um die Sicherheit kümmern Vorsicht bei der Auswahl der Algorithmen und bei der kontinuierlichen Überarbeitung Ihrer Sicherheitsstärken, da die Fähigkeiten von Angreifern auch nur in eine Richtung gehen. Daher wäre es unklug, Git als Vorbild zu nehmen, insbesondere als Zweck Die Verwendung von SHA-1 soll keine kryptografische Sicherheit sein.
Dies ist eine Diskussion über die Dringlichkeit der Migration von SHA1 für Mercurial, gilt jedoch auch für Git: https://www.mercurial-scm.org/wiki/mpm/SHA1
Kurz gesagt: Wenn Sie heute nicht besonders fleißig sind, haben Sie viel schlimmere Schwachstellen als sha1. Trotzdem begann Mercurial vor über 10 Jahren, sich auf die Abwanderung von sha1 vorzubereiten.
Seit Jahren wird daran gearbeitet, die Datenstrukturen und Protokolle von Mercurial für die Nachfolger von SHA1 nachzurüsten. Mit der Einführung von RevlogNG wurde vor über 10 Jahren in Mercurial 0.9 Speicherplatz für größere Hashes in unserer Revlog-Struktur zugewiesen. Das kürzlich eingeführte Bundle2-Format unterstützt den Austausch verschiedener Hash-Typen über das Netzwerk. Die einzigen verbleibenden Teile sind die Wahl einer Ersatzfunktion und die Wahl einer Abwärtskompatibilitätsstrategie.
Wenn git nicht vor Mercurial von sha1 weg migriert, können Sie jederzeit eine weitere Sicherheitsstufe hinzufügen, indem Sie einen lokalen Mercurial-Spiegel mit hg-git beibehalten .
Es gibt jetzt einen Übergangsplan zu einem stärkeren Hash, so dass es so aussieht, als würde in Zukunft ein modernerer Hash als SHA-1 verwendet. Aus dem aktuellen Übergangsplan :
Einige in Betracht gezogene Hashes sind SHA-256, SHA-512/256, SHA-256x16, K12 und BLAKE2bp-256