Czytałem o tym, że Git używa skrótu SHA-1 jako identyfikatora zmiany. Dlaczego nie używa nowocześniejszej wersji SHA?
Czytałem o tym, że Git używa skrótu SHA-1 jako identyfikatora zmiany. Dlaczego nie używa nowocześniejszej wersji SHA?
Odpowiedzi:
Dlaczego nie używa nowocześniejszej wersji SHA?
Grudzień 2017: Będzie. Git 2.16 (Q1 2018) jest pierwszą wersją, która ilustruje i realizuje ten zamiar.
Uwaga: zobacz Git 2.19 poniżej: będzie to SHA-256 .
Git 2.16 zaproponuje infrastrukturę do zdefiniowania funkcji skrótu używanej w Gicie i podejmie próbę zbadania tego w różnych ścieżkach kodowych.
Zobacz commit c250e02 (28 listopada 2017) autorstwa Ramsay Jones (``) .
Zobacz: commit eb0ccfd , commit 78a6766 , commit f50e766 , commit abade65 (12 listopada 2017) autor: brian m. carlson ( bk2204
) .
(Scalone przez Junio C Hamano - gitster
- w zatwierdzeniu 721cc43 , 13 grudnia 2017 r.)
Dodaj strukturę reprezentującą algorytm skrótu
Ponieważ w przyszłości chcemy obsługiwać dodatkowy algorytm wyznaczania wartości skrótu, dodaj strukturę reprezentującą algorytm wyznaczania wartości skrótu i wszystkie dane, które muszą z nim współgrać .
Dodaj stałą, aby umożliwić łatwe wyliczanie algorytmów wyznaczania wartości skrótu .
Zaimplementuj funkcję,typedefs
aby utworzyć abstrakcyjny interfejs API, który może być używany przez dowolny algorytm wyznaczania wartości skrótu, oraz opakowania dla istniejących funkcji SHA1, które są zgodne z tym interfejsem API.Ujawnij wartość rozmiaru szesnastkowego, a także rozmiaru binarnego .
Chociaż jedna będzie zawsze dwa razy inna, obie wartości są używane niezwykle często w całej bazie kodu i zapewniają obie prowadzą do lepszej czytelności.Nie dołączaj wpisu do struktury algorytmu wyznaczania wartości skrótu dla pustego identyfikatora obiektu.
Ponieważ ta wartość to same zera, można użyć dowolnego zerowego identyfikatora obiektu o odpowiedniej wielkości i nie ma potrzeby zapisywania danego identyfikatora na podstawie skrótu.Obecny plan przejścia funkcji skrótu przewiduje czas, w którym będziemy akceptować dane wejściowe od użytkownika, które mogą być w formacie SHA-1 lub NewHash.
Ponieważ nie możemy wiedzieć, którą podał użytkownik, dodaj stałą reprezentującą nieznany algorytm, abyśmy mogli wskazać, że musimy sprawdzić poprawną wartość.
Zintegruj obsługę algorytmu wyznaczania wartości skrótu z konfiguracją repozytorium
W przyszłych wersjach Gita planujemy obsługę dodatkowego algorytmu mieszania.
Zintegruj wyliczanie algorytmów wyznaczania wartości skrótu z konfiguracją repozytorium i przechowuj wskaźnik do wyliczonych danych w repozytorium struct .
Oczywiście obecnie obsługujemy tylko SHA-1, więc zakoduj tę wartość na stałe wread_repository_format
.
W przyszłości wyliczymy tę wartość z konfiguracji.Dodaj stałą,
the_hash_algo
która wskazuje nahash_algo
wskaźnik struktury w repozytorium global.
Zauważ, że jest to skrót używany do serializacji danych na dysk, a nie skrót używany do wyświetlania elementów użytkownikowi.
Plan przejścia przewiduje, że mogą się one różnić.
W przyszłości możemy dodać dodatkowy element (powiedzmyui_hash_algo
), aby uwzględnić ten przypadek.
Aktualizacja z sierpnia 2018 r. Dla Git 2.19 (III kw. 2018 r.) Wydaje się, że Git wybiera SHA-256 jako NewHash.
Zobacz commit 0ed8d8d (4 sierpnia 2018) autorstwa Jonathana Niedera ( artagnon
) .
Zobacz zatwierdzenie 13f5e09 (25 lipca 2018) autorstwa Ævara Arnfjörð Bjarmasona ( avar
) .
(Scalone przez Junio C Hamano - gitster
- w zobowiązaniu 34f2297 , 20 sierpnia 2018 r.)
doc
hash-function-transition
: wybierz SHA-256 jako NewHashZ punktu widzenia bezpieczeństwa wydaje się, że SHA-256, BLAKE2, SHA3-256, K12 itd. Mają podobne właściwości zabezpieczające.
Wszystkie są dobrymi opcjami z punktu widzenia bezpieczeństwa.SHA-256 ma wiele zalet:
Jest już od jakiegoś czasu, jest szeroko stosowany i jest obsługiwany przez prawie każdą bibliotekę kryptograficzną (OpenSSL, mbedTLS, CryptoNG, SecureTransport itp.).
Porównując z SHA1DC, większość wektoryzowanych implementacji SHA-256 jest rzeczywiście szybsza, nawet bez akceleracji.
Jeśli robimy podpisy za pomocą OpenPGP (lub nawet, jak przypuszczam, CMS), będziemy używać SHA-2, więc nie ma sensu, aby nasze zabezpieczenia zależały od dwóch oddzielnych algorytmów, gdy jeden z nich sam może złamać bezpieczeństwo, kiedy możemy po prostu na nim polegać.
Więc to jest SHA-256 .
Zaktualizuj dokument projektu przejścia funkcji skrótu, aby to powiedzieć.Po tej poprawce nie ma już żadnych wystąpień ciągu „
NewHash
”, z wyjątkiem niepowiązanego użycia od 2008 r. Jako nazwy zmiennej w programiet/t9700/test.pl
.
Możesz zobaczyć, jak postępuje przejście na SHA 256 w Git 2.20 (Q4 2018):
Patrz popełnienia 0d7c419 , popełnienia dda6346 , popełnienia eccb5a5 , popełnienia 93eb00f , popełnienia d8a3a69 , popełnienia fbd0e37 , popełnienia f690b6b , popełnienia 49d1660 , popełnienia 268babd , popełnienia fa13080 , popełnienia 7b5e614 , popełnienia 58ce21b , popełnienia 2f0c9e9 , popełnienia 825544a (15 października 2018) przez brian m . carlson ( bk2204
) .
Zobacz commit 6afedba (15 października 2018) autorstwa SZEDER Gábor ( szeder
) .
(Scalone przezJunio C Hamano - gitster
- in commit d829d49 , 30 października 2018)
zastąpić stałe zakodowane na stałe
Zastąp kilka stałych opartych na 40 odnośnikach do
GIT_MAX_HEXSZ
lubthe_hash_algo
, stosownie do przypadku.
Przekonwertuj wszystkie zastosowania,GIT_SHA1_HEXSZ
aby użyćthe_hash_algo
, aby były odpowiednie dla dowolnej długości skrótu.
Zamiast używać zakodowanej na stałe stałej dla rozmiaru szesnastkowego identyfikatora obiektu, przełącz się, aby używać obliczonego wskaźnika zparse_oid_hex
tych punktów po przeanalizowanym identyfikatorze obiektu.
GIT_SHA1_HEXSZ
jest dalej usuwany / zastępowany przez Git 2.22 (Q2 2019) i zatwierdzony d4e568b .
To przejście jest kontynuowane w Git 2.21 (Q1 2019), który dodaje hash sha-256 i podłącza go do kodu, aby umożliwić budowanie Gita za pomocą „NewHash”.
Zobacz popełnić 4b4e291 , popełnić 27dc04c , popełnić 13eeedb , popełnić c166599 , popełnić 37649b7 , popełnić a2ce0a7 , popełnić 50c817e , popełnić 9a3a0ff , popełnić 0dab712 , popełnić 47edb64 (14 lis 2018) i popełnić 2f90b9d , popełnić 1ccf07c (22 października 2018) przez brian m . carlson ( bk2204
) .
(Scalone przez Junio C Hamano - gitster
- w zatwierdzeniu 33e4ae9 , 29 stycznia 2019 r.)
Dodaj podstawową implementację obsługi SHA-256 (luty 2019)
SHA-1 jest słaby i musimy przejść do nowej funkcji skrótu.
Od jakiegoś czasu nazywamy tę nową funkcjęNewHash
.
Ostatnio zdecydowaliśmy się na SHA-256 jakoNewHash
.
Powody wyboru SHA-256 są opisane w tym wątku oraz w historii zatwierdzeń dokumentu przejścia funkcji skrótu.Dodaj podstawową implementację opartą na SHA-256
libtomcrypt
, która jest w domenie publicznej.
Zoptymalizuj go i zrestrukturyzuj, aby spełniał nasze standardy kodowania.
Pobierz aktualizację i końcowe funkcje z implementacji bloku SHA-1, ponieważ wiemy, że działają one poprawnie ze wszystkimi kompilatorami. Ta implementacja jest wolniejsza niż SHA-1, ale bardziej wydajne implementacje zostaną wprowadzone w przyszłych zatwierdzeniach.Połącz SHA-256 na liście algorytmów wyznaczania wartości skrótu i dodaj test, czy algorytm działa poprawnie.
Zauważ, że z tą poprawką nadal nie można przełączyć się na używanie SHA-256 w Git.
Potrzebne są dodatkowe poprawki, aby przygotować kod do obsługi większego algorytmu wyznaczania wartości skrótu i dalsze poprawki testowe.
hash
: dodaj implementację SHA-256 przy użyciu OpenSSLMamy już dostępne procedury OpenSSL dla SHA-1, więc dodaj również procedury dla SHA-256.
Na Core i7-6600U ta implementacja SHA-256 wypada korzystnie w porównaniu z implementacją SHA1DC SHA-1:
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
: dodaj implementację SHA-256 przy użyciulibgcrypt
Generalnie uzyskuje się lepszą wydajność z procedur kryptograficznych napisanych w asemblerze niż C, i dotyczy to również SHA-256.
Ponadto większość dystrybucji Linuksa nie może rozpowszechniać Git połączonego z OpenSSL z powodów licencyjnych.Większość systemów z GnuPG również będzie mieć
libgcrypt
, ponieważ jest to zależność od GnuPG.
libgcrypt
jest również szybszy niż implementacja SHA1DC dla wiadomości o wielkości kilku KiB i większych.Dla porównania, na Core i7-6600U ta implementacja przetwarza 16 fragmentów KiB z prędkością 355 MiB / s, podczas gdy SHA1DC przetwarza równoważne fragmenty z szybkością 337 MiB / s.
Ponadto libgcrypt jest licencjonowany w ramach licencji LGPL 2.1, która jest zgodna z GPL. Dodaj implementację SHA-256, która używa libgcrypt.
Aktualizacja jest kontynuowana w Git 2.24 (Q4 2019)
Zobacz zatwierdzenie aaa95df , zatwierdzenie be8e172 , zatwierdzenie 3f34d70 , zatwierdzenie fc06be3 , zatwierdzenie 69fa337 , zatwierdzenie 3a4d7aa , zatwierdzenie e0cb7cd , zatwierdzenie 8d4d86b , zatwierdzenie f6ca67d , zatwierdzenie dd336a5 , zatwierdzenie 894c0f6 , zatwierdzenie 3a4d7aa , zatwierdzenie e0cb7cd , zatwierdzenie 8d4d86b , zatwierdzenie f6ca67d , zatwierdzenie dd336a5 , zatwierdzenie 894c0f6 , zatwierdzenie 4439c7a , zatwierdzenie , zatwierdzenie e0cb7cd , zatwierdzenie 8d4d86b , zatwierdzenie f6ca67d , zatwierdzenie dd336a5 , zatwierdzenie 894c0f6 , zatwierdzenie 4439c7a , zatwierdzenie , zatwierdzenie 703d2d4 , zatwierdzenie 9d958cc , zatwierdzenie 7962e04 , zatwierdzenie opłaty4930(18 sierpnia 2019) autor: brian M. carlson ( bk2204
) .
(Scalone przez Junio C Hamano - gitster
- w zatwierdzeniu 676278f , 11 października 2019 r.)
Zamiast używać
GIT_SHA1_HEXSZ
stałych i zakodowanych na stałe, przełącz się na usingthe_hash_algo
.
W Git 2.26 (Q1 2020) skrypty testowe są gotowe na dzień, w którym nazwy obiektów będą używać SHA-256.
Zobacz zatwierdzenie 277eb5a , zatwierdzenie 44b6c05 , zatwierdzenie 7a868c5 , zatwierdzenie 1b8f39f , zatwierdzenie a8c17e3 , zatwierdzenie 8320722 , zatwierdzenie 74ad99b , zatwierdzenie ba1be1a , zatwierdzenie cba472d , zatwierdzenie 82d5aeb , zatwierdzenie 3c5e65c , zatwierdzenie a8c17e3 , zatwierdzenie 8320722 , zatwierdzenie 74ad99b , zatwierdzenie ba1be1a , zatwierdzenie cba472d , zatwierdzenie 82d5aeb , zatwierdzenie 3c5e65c , zatwierdzenie 235d3cd , zatwierdzenie 1d86fa8f , zatwierdzenie , zatwierdzenie 717c939 , zatwierdzenie 08a9dd8 , zatwierdzenie 215b60b , zatwierdzenie 194264c(21 grudnia 2019) autorstwa brian M. carlson ( bk2204
) .
(Scalone przez Junio C Hamano - gitster
- w zatwierdzeniu f52ab33 , 05 lutego 2020 r.)
Przykład:
t4204
: uniezależnia rozmiar skrótuPodpisał: brian m. Carlson
Użyj
$OID_REGEX
zamiast zakodowanego wyrażenia regularnego.
Więc zamiast używać:
grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
Testy używają
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
I OID_REGEX
pochodzi z commit bdee9cd (13 maja 2018) przez brian m. carlson ( bk2204
) .
(Scalony przez Junio C Hamano - gitster
- w zatwierdzeniu 9472b13 , 30 maja 2018 r., Git v2.18.0-rc0)
t/test-lib
: przedstawiaćOID_REGEX
Podpisał: brian m. Carlson
Obecnie mamy zmienną,
$_x40,
która zawiera wyrażenie regularne pasujące do pełnej 40-znakowej stałej szesnastkowej.Jednak w przypadku
NewHash
będziemy mieć identyfikatory obiektów dłuższe niż 40 znaków.W takim przypadku
$_x40
nazwa będzie myląca.Utwórz
$OID_REGEX
zmienną, która zawsze będzie odzwierciedlać wyrażenie regularne pasujące do odpowiedniego identyfikatora obiektu, niezależnie od długości bieżącego skrótu.
I jeszcze do testów:
Zobacz zatwierdzenie f303765 , zatwierdzenie edf0424 , zatwierdzenie 5db24dc , zatwierdzenie d341e08 , zatwierdzenie 88ed241 , zatwierdzenie 48c10cc , zatwierdzenie f7ae8e6 , zatwierdzenie e70649b , zatwierdzenie a30f93b , zatwierdzenie a79eec2 , zatwierdzenie 796d138 , zatwierdzenie 417e45e , zatwierdzenie 48c10cc , zatwierdzenie f7ae8e6 , zatwierdzenie e70649b , zatwierdzenie a30f93b , zatwierdzenie a79eec2 , zatwierdzenie 796d138 , zatwierdzenie 417e45e , zatwierdzenie dfa5f53 , zatwierdzenie, 7243edf9f 07877f3 , zatwierdzenie 6025e89 , zatwierdzenie 7b1a182 , zatwierdzenie 94db7e3 ,commit db12505 (07 lutego 2020) przez brian bk2204
M. carlson ( ) .
(Scalony przez Junio C Hamano - gitster
- w zobowiązaniu 5af345a , 17 lutego 2020 r.)
t5703
: spraw, aby test działał z SHA-256Podpisał: brian m. Carlson
W tym teście użyto identyfikatora obiektu o długości 40 znaków szesnastkowych, co spowodowało, że test nie tylko nie przeszedł pomyślnie, ale zawiesił się po uruchomieniu z SHA-256 jako hashem.
Zmień tę wartość na stały fikcyjny identyfikator obiektu za pomocą
test_oid_init
itest_oid
.Ponadto upewnij się, że wyodrębniamy identyfikator obiektu o odpowiedniej długości za pomocą cięcia z polami zamiast stałej długości.
Niektóre ścieżki kodowe otrzymały instancję repozytorium jako parametr do pracy w repozytorium, ale przekazały the_repository
instancję do jej wywołań, które zostały (nieco) oczyszczone za pomocą Git 2.26 (Q1 2020).
Zobacz commit b98d188 , commit 2dcde20 , commit 7ad5c44 , commit c8123e7 , commit 5ec9b8a , commit a651946 , commit eb999b3 (30 stycznia 2020) autorstwa Matheus Tavares ( matheustavares
) .
(Scalone przez Junio C Hamano - gitster
- w zatwierdzeniu 78e67cd , 14 lutego 2020 r.)
sha1-file
: pozwalacheck_object_signature()
obsłużyć dowolne repozytoriumPodpisał: Matheus Tavares
Niektórzy wywołujący
check_object_signature()
mogą pracować na dowolnych repozytoriach, ale repozytorium nie jest przekazywane do tej funkcji. Zamiast tegothe_repository
jest zawsze używany wewnętrznie.
Aby naprawić możliwe niespójności, zezwól funkcji na otrzymanie repozytorium struktury i przekaż wywoływaczom obsługiwane repozytorium.
Oparte na:
sha1-file
: przejdźgit_hash_algo
dohash_object_file()
Podpisał: Matheus Tavares
Pozwól
hash_object_file()
pracować nad dowolnymi repozytoriami, wprowadzającgit_hash_algo
parametr. Zmień wywołujące, które mają wskaźnik repozytorium struktury w swoim zakresie, aby przekazać dalejgit_hash_algo
ze wspomnianego repozytorium.
Dla wszystkich innych dzwoniących przekaż dalejthe_hash_algo
, który był już używany wewnętrznie o godziniehash_object_file()
.
Ta funkcjonalność zostanie użyta w następnej łatce, abycheck_object_signature()
móc pracować na dowolnych repozytoriach (które z kolei zostaną użyte do naprawienia niespójności wobject.c
: parse_object ()).
git rev-parse
może teraz wydrukować, jaki hash będzie używany: stackoverflow.com/a/58862319/6309 . A puste drzewo ma nowy identyfikator SHA2: stackoverflow.com/a/9766506/6309
AKTUALIZACJA : Powyższe pytanie i ta odpowiedź pochodzą z 2015 roku. Od tego czasu Google ogłosił pierwszą kolizję SHA-1: https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
Oczywiście mogę tylko spekulować z zewnątrz, patrząc na to, dlaczego Git nadal używa SHA-1, ale może to być jeden z powodów:
unsigned char[20]
bufory w każdym miejscu ;-), o wiele łatwiej jest zaprogramować zwinność kryptograficzną na początku, niż później.Niektóre linki:
Moim osobistym zdaniem jest to, że chociaż praktyczne ataki są prawdopodobnie trochę wolne, a nawet jeśli już się pojawią, ludzie prawdopodobnie początkowo złagodzą je środkami innymi niż zmiana samego algorytmu skrótu, że jeśli dbasz o bezpieczeństwo, powinieneś się mylić po stronie ostrożności przy wyborze algorytmów i ciągłego ulepszania swoich mocnych stron bezpieczeństwa, ponieważ możliwości atakujących również idą tylko w jednym kierunku, więc nierozsądne byłoby przyjmowanie Gita jako wzoru do naśladowania, zwłaszcza jako jego celu w używanie SHA-1 nie jest rzekomo zabezpieczeniem kryptograficznym.
To jest dyskusja na temat pilności migracji z SHA1 dla Mercurial, ale dotyczy to również Git: https://www.mercurial-scm.org/wiki/mpm/SHA1
Krótko mówiąc: jeśli nie jesteś dzisiaj wyjątkowo pracowity, masz znacznie gorsze luki w zabezpieczeniach niż sha1. Mimo to Mercurial rozpoczął ponad 10 lat temu przygotowania do migracji z sha1.
od lat trwają prace nad modernizacją struktur danych i protokołów Mercurial dla następców SHA1. Przestrzeń dyskowa została przydzielona dla większych hashów w naszej strukturze revlog ponad 10 lat temu w Mercurial 0.9 wraz z wprowadzeniem RevlogNG. Wprowadzony niedawno format bundle2 obsługuje wymianę różnych typów skrótów w sieci. Jedyne pozostałe elementy to wybór funkcji zastępczej i wybór strategii kompatybilności wstecznej.
Jeśli git nie migruje z sha1 przed Mercurialem, zawsze możesz dodać kolejny poziom bezpieczeństwa, utrzymując lokalny serwer lustrzany Mercurial z hg-git .
Obecnie istnieje plan przejścia na silniejszy hash, więc wygląda na to, że w przyszłości będzie używany nowocześniejszy hash niż SHA-1. Z obecnego planu przejścia :
Niektóre z rozważanych skrótów to SHA-256, SHA-512/256, SHA-256x16, K12 i BLAKE2bp-256