Почему Git не использует более современный SHA?


91

Я читал о том, что Git использует дайджест SHA-1 в качестве идентификатора ревизии. Почему не используется более современная версия SHA?


2
Производительность - единственная причина, по которой я могу думать, SHA-1 быстрее, чем SHA-2. Лично я считаю это плохим решением, поскольку сопротивление столкновению SHA-1 довольно слабое.
CodesInChaos

4
stackoverflow.com/questions/9392365/… - не точное совпадение, но покрывает схожие
темы

6
Это обсуждалось в списке рассылки git в 2006 году. См. Всю цепочку . Подводя итог, Линус тогда сказал, что SHA-1 должен быть достаточно уникальным, чтобы не возникало коллизий, что так и есть. SHA-1 не является функцией безопасности для git. «Любой, кто слепо принимает данные из ненадежных источников, попадает в такую ​​ловушку во многих других отношениях, что хэш-атака просто не заметна». - Линус
tbc0

28
Обновление: коллизии SHA-1 теперь в дикой природе shattered.it
drewr

2
Первый квартал 2018 г .: усилия по поддержке альтернативного SHA-алгоритма продолжаются: см. Мой ответ ниже
VonC,

Ответы:


62

Почему не используется более современная версия SHA?

Декабрь 2017: Будет. И Git 2.16 (Q1 2018) - первая версия, которая иллюстрирует и реализует это намерение.

Примечание: см. Git 2.19 ниже: это будет SHA-256 .

Git 2.16 предложит инфраструктуру для определения того, какая хэш-функция используется в Git, и начнет работу по ее проникновению в различные пути кода.

См. Коммит c250e02 (28 ноября 2017 г.) Рамси Джонса (``) .
См. Commit eb0ccfd , commit 78a6766 , commit f50e766 , commit abade65 (12 ноября 2017 г.), автор brian m. Карлсон ( bk2204) .
(Объединено Junio ​​C Hamano - gitster- в коммите 721cc43 , 13 декабря 2017 г.)


Добавить структуру, представляющую алгоритм хеширования

Поскольку в будущем мы хотим поддерживать дополнительный алгоритм хеширования, добавляем структуру, которая представляет алгоритм хеширования и все данные, которые должны сопровождать его .
Добавьте константу, чтобы упростить перечисление алгоритмов хеширования .
Реализуйте функциюtypedefs для создания абстрактного API, который может использоваться любым алгоритмом хеширования, и оболочки для существующих функций SHA1, которые соответствуют этому API.

Выставьте значение для шестнадцатеричного и двоичного размера .
Хотя одно всегда будет в два раза больше, оба значения очень часто используются во всей кодовой базе и обеспечивают улучшение читаемости.

Не включайте запись в структуру хеш-алгоритма для идентификатора нулевого объекта.
Поскольку это значение полностью равно нулю, можно использовать любой идентификатор объекта с нулевым значением подходящего размера, и нет необходимости сохранять данный идентификатор для каждого хеша.

Текущий план перехода к хэш-функции предусматривает время, когда мы будем принимать ввод от пользователя, который может быть в формате SHA-1 или в формате NewHash.
Поскольку мы не можем знать, что предоставил пользователь, добавьте константу, представляющую неизвестный алгоритм, чтобы мы могли указать, что мы должны найти правильное значение.


Интегрируйте поддержку хеш-алгоритма с настройкой репо

В будущих версиях Git мы планируем поддерживать дополнительный алгоритм хеширования.
Интегрируйте перечисление алгоритмов хеширования с настройкой репозитория и сохраните указатель на перечисленные данные в репозитории структур .
Конечно, в настоящее время мы поддерживаем только SHA-1, поэтому жестко запрограммируйте это значение в read_repository_format .
В дальнейшем мы перечислим это значение из конфигурации.

Добавьте константу,the_hash_algo которая указывает на hash_algoуказатель структуры в репозитории global.
Обратите внимание, что это хеш, который используется для сериализации данных на диск, а не хеш, который используется для отображения элементов пользователю.
План перехода предполагает, что они могут быть другими.
Мы можем добавить в будущем дополнительный элемент (скажем, ui_hash_algo), чтобы обеспечить этот случай.


Обновление августа 2018 г. для Git 2.19 (3 ​​квартал 2018 г.) Git, похоже, выбирает SHA-256 в качестве NewHash.

См. Коммит 0ed8d8d (4 августа 2018 г.) Джонатана Нидера ( artagnon) .
См. Коммит 13f5e09 (25 июля 2018 г.), сделанный var Arnfjör Bjarmason ( avar) .
(Объединено Junio ​​C Hamano - gitster- в коммите 34f2297 , 20 августа 2018 г.)

документhash-function-transition : выберите SHA-256 как NewHash

С точки зрения безопасности кажется, что SHA-256, BLAKE2, SHA3-256, K12 и т. Д. Имеют схожие свойства безопасности.
Все варианты хороши с точки зрения безопасности.

SHA-256 имеет ряд преимуществ:

  • Он существует уже некоторое время, широко используется и поддерживается практически каждой криптографической библиотекой (OpenSSL, mbedTLS, CryptoNG, SecureTransport и т. Д.).

  • Если сравнить с SHA1DC, большинство реализаций векторизованного SHA-256 действительно быстрее, даже без ускорения.

  • Если мы делаем подписи с помощью OpenPGP (или даже, я полагаю, CMS), мы собираемся использовать SHA-2, поэтому нет смысла полагать нашу безопасность на два отдельных алгоритма, когда любой из них в одиночку может нарушить безопасность, когда мы можем просто положиться на одного.

Итак, SHA-256 .
Обновите проектную документацию по переходу хэш-функции, чтобы указать это.

После этого патча не осталось экземпляров строки " NewHash", за исключением несвязанного использования с 2008 года в качестве имени переменной в t/t9700/test.pl .


Вы можете увидеть этот переход на SHA 256 в Git 2.20 (4 квартал 2018 г.):

См совершают 0d7c419 , совершает dda6346 , совершает eccb5a5 , совершает 93eb00f , совершает d8a3a69 , совершают fbd0e37 , совершает f690b6b , совершает 49d1660 , совершает 268babd , совершает fa13080 , совершает 7b5e614 , совершают 58ce21b , совершает 2f0c9e9 , совершает 825544a (15 октября 2018) по Брайан м . Карлсон ( bk2204) .
См. Commit 6afedba (15 октября 2018 г.) Седера Габора ( szeder) .
(ОбъединеноJunio ​​C Hamano - gitster- в коммите d829d49 , 30 октября 2018 г.)

заменить жестко запрограммированные константы

Замените несколько констант на основе 40 ссылками на GIT_MAX_HEXSZили the_hash_algo, если необходимо.
Преобразуйте все варианты GIT_SHA1_HEXSZиспользования, the_hash_algoчтобы они подходили для любой заданной длины хэша.
Вместо использования жестко запрограммированной константы для размера шестнадцатеричного идентификатора объекта переключитесь на использование вычисленного указателя из parse_oid_hexэтих точек после идентификатора анализируемого объекта.

GIT_SHA1_HEXSZдалее удаляется / заменяется на Git 2.22 (второй квартал 2019 г.) и фиксируется d4e568b .


Этот переход продолжается с Git 2.21 (первый квартал 2019 г.), который добавляет хеш sha-256 и вставляет его в код, позволяя создавать Git с «NewHash».

См совершают 4b4e291 , совершают 27dc04c , совершают 13eeedb , совершают c166599 , совершают 37649b7 , совершают a2ce0a7 , совершают 50c817e , совершают 9a3a0ff , совершают 0dab712 , совершают 47edb64 (14 Nov 2018), а также совершать 2f90b9d , совершают 1ccf07c (22 октября 2018) по Брайан м . Карлсон ( bk2204) .
(Объединено Junio ​​C Hamano - gitster- в коммите 33e4ae9 , 29 января 2019 г.)

Добавить базовую реализацию поддержки SHA-256 (февраль 2019 г.)

SHA-1 слабый, и нам нужно перейти на новую хеш-функцию.
Некоторое время мы называли эту новую функцию NewHash.
Недавно мы решили выбрать SHA-256 какNewHash .
Причины выбора SHA-256 изложены в этом потоке и в истории фиксации документа перехода хэш-функции.

Добавьте базовую реализацию SHA-256 на основе off libtomcrypt, которая находится в свободном доступе.
Оптимизируйте его и реструктурируйте в соответствии с нашими стандартами кодирования.
Вытяните функции update и final из реализации блока SHA-1, поскольку мы знаем, что они правильно работают со всеми компиляторами. Эта реализация медленнее, чем SHA-1, но в будущих коммитах будут представлены более производительные реализации.

Подключите SHA-256 к списку алгоритмов хеширования и добавьте проверку правильности работы алгоритма.

Обратите внимание, что с этим патчем по-прежнему невозможно переключиться на использование SHA-256 в Git.
Дополнительные исправления необходимы, чтобы подготовить код для обработки более крупного алгоритма хеширования, и необходимы дополнительные исправления тестирования.

hash: добавить реализацию SHA-256 с использованием OpenSSL

У нас уже есть подпрограммы OpenSSL для SHA-1, так что добавьте подпрограммы и для SHA-256.

На Core i7-6600U эта реализация SHA-256 выгодно отличается от реализации 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: добавить реализацию SHA-256, используя libgcrypt

Как правило, криптографические процедуры, написанные на ассемблере, получают лучшую производительность, чем C, и это также верно для SHA-256.
Кроме того, большинство дистрибутивов Linux не могут распространять Git, связанный с OpenSSL, по причинам лицензирования.

Большинство систем с GnuPG также будут иметь libgcrypt, так как это зависимость от GnuPG.
libgcryptтакже быстрее, чем реализация SHA1DC для сообщений размером несколько КиБ и больше.

Для сравнения: на Core i7-6600U эта реализация обрабатывает блоки размером 16 КиБ со скоростью 355 МБ / с, тогда как SHA1DC обрабатывает эквивалентные блоки со скоростью 337 МБ / с.

Кроме того, libgcrypt распространяется под лицензией LGPL 2.1, которая совместима с GPL. Добавьте реализацию SHA-256, использующую libgcrypt.


Обновление продолжается с Git 2.24 (4 квартал 2019 г.)

См совершать aaa95df , совершать be8e172 , совершает 3f34d70 , совершает fc06be3 , совершает 69fa337 , совершает 3a4d7aa , совершает e0cb7cd , совершает 8d4d86b , совершают f6ca67d , совершают dd336a5 , совершает 894c0f6 , совершает 4439c7a , совершает 95518fa , совершает e84f357 , совершает fe9fec4 , совершает 976ff7e , совершить 703d2d4 , фиксация 9d958cc , фиксация 7962e04 , комиссия за фиксацию 4930(18 августа 2019 г.) Брайан М. Карлсон ( bk2204) .
(Объединено Junio ​​C Hamano - gitster- в коммите 676278f , 11 октября 2019 г.)

Вместо использования GIT_SHA1_HEXSZжестко запрограммированных констант переключитесь на using the_hash_algo.


С Git 2.26 (Q1 2020) тестовые сценарии готовы к тому дню, когда имена объектов будут использовать SHA-256.

См совершать 277eb5a , совершать 44b6c05 , совершают 7a868c5 , совершают 1b8f39f , совершают a8c17e3 , совершают 8320722 , совершают 74ad99b , совершают ba1be1a , совершают cba472d , совершают 82d5aeb , совершают 3c5e65c , совершают 235d3cd , совершают 1d86c8f , совершают 525a7f1 , совершают 7a1bcb2 , совершают cb78f4f , совершить 717c939 , фиксация 08a9dd8 , фиксация 215b60b , фиксация 194264c(21 декабря 2019 г.) Брайан М. Карлсон ( bk2204) .
(Объединено Junio ​​C Hamano - gitster- в фиксации f52ab33 , 5 февраля 2020 г.)

Пример:

t4204: сделать размер хэша независимым

Подписано: brian m. Карлсон

Используйте $OID_REGEXвместо жестко заданного регулярного выражения.

Итак, вместо использования:

grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output

Тесты используют

grep "^$OID_REGEX $(git rev-parse HEAD)$" output

И OID_REGEXисходит из фиксации bdee9cd (13 мая 2018 г.), созданной brian m. Карлсон ( bk2204) .
(Объединено Junio ​​C Hamano - gitster- в фиксации 9472b13 , 30 мая 2018 г., Git v2.18.0-rc0)

t/test-lib: вводить OID_REGEX

Подписано: brian m. Карлсон

В настоящее время у нас есть переменная, $_x40,которая содержит регулярное выражение, которое соответствует полной шестнадцатеричной константе из 40 символов.

Однако у NewHashнас будут идентификаторы объектов длиной более 40 символов.

В таком случае имя $_x40будет запутанным.

Создайте $OID_REGEXпеременную, которая всегда будет отражать регулярное выражение, соответствующее соответствующему идентификатору объекта, независимо от длины текущего хэша.

И еще для тестов:

См совершать f303765 , совершать edf0424 , совершают 5db24dc , совершают d341e08 , совершают 88ed241 , совершают 48c10cc , совершают f7ae8e6 , совершают e70649b , совершают a30f93b , совершают a79eec2 , совершают 796d138 , совершают 417e45e , совершают dfa5f53 , совершают f743e8f , совершают 72f936b , совершают 5df0f11 , совершить 07877f3 , совершить 6025e89 , совершить 7b1a182 , совершить 94db7e3 ,commit db12505 (7 февраля 2020 г.) автор: brian m. Карлсон ( bk2204) .
(Объединено Junio ​​C Hamano - gitster- в коммите 5af345a , 17 февраля 2020 г.)

t5703: сделать тестовую работу с SHA-256

Подписано: brian m. Карлсон

В этом тесте использовался идентификатор объекта длиной 40 шестнадцатеричных символов, из-за чего тест не только не проходил, но и зависал при запуске с SHA-256 в качестве хэша.

Измените это значение на фиксированный идентификатор фиктивного объекта с помощью test_oid_initи test_oid.

Кроме того, убедитесь, что мы извлекаем идентификатор объекта соответствующей длины, используя вырезание с полями вместо фиксированной длины.


Некоторым кодовым путям был предоставлен экземпляр репозитория в качестве параметра для работы в репозитории, но the_repositoryэкземпляр передавался его вызывающим объектам, что было (несколько) очищено с помощью Git 2.26 (первый квартал 2020 г.).

См. Commit b98d188 , commit 2dcde20 , commit 7ad5c44 , commit c8123e7 , commit 5ec9b8a , commit a651946 , commit eb999b3 (30 Jan 2020) by Matheus Tavares ( matheustavares) .
(Объединено Junio ​​C Hamano - gitster- в коммите 78e67cd , 14 февраля 2020 г.)

sha1-file: разрешить check_object_signature()обработку любого репо

Подписано: Матеус Таварес

Некоторые вызывающие объекты check_object_signature()могут работать с произвольными репозиториями, но репо не передается в эту функцию. Вместо этого the_repositoryвсегда используется для внутренних целей.
Чтобы исправить возможные несоответствия, разрешите функции получить репозиторий структур и заставьте эти вызывающие стороны передавать обрабатываемое репо.

По материалам:

sha1-file: перейти git_hash_algoкhash_object_file()

Подписано: Матеус Таварес

Разрешить hash_object_file()работать с произвольными репозиториями, введя git_hash_algoпараметр. Измените вызывающих абонентов, которые имеют указатель на репозиторий структуры в своей области, чтобы они передавали git_hash_algoиз указанного репо.
Для всех остальных вызывающих абонентов передайте the_hash_algo, который уже использовался внутри hash_object_file().
Эта функция будет использоваться в следующем патче, чтобы check_object_signature()иметь возможность работать с произвольными репозиториями (что, в свою очередь, будет использоваться для исправления несоответствия в object.c: parse_object ()).


1
Кроме того, не забывайте, что Git v2.13.0 и более поздние версии впоследствии по умолчанию перешли на усиленную реализацию SHA-1, которая не уязвима для атаки SHAttered. См. Stackoverflow.com/a/43355918/6309
VonC

1: Google произвел столкновение shattered.io в феврале 2017 года (ориентировочная стоимость 110 000 долларов) 2: Наньянский технологический университет произвел столкновение sha-mbles.github.io в январе 2019 года (ориентировочная стоимость от 11 до 45 тысяч долларов). Git для перехода к SHA1
bristweb

@bristweb "Пришло время Git отказаться от SHA1": я согласен, и с Git 2.25 (выпущенным сегодня) этот шаг является удачным. git rev-parseтеперь можно распечатать, какой хеш будет использоваться: stackoverflow.com/a/58862319/6309 . И пустое дерево имеет новый идентификатор SHA2: stackoverflow.com/a/9766506/6309
VonC

Благодаря расширяемости этого алгоритма хеширования CRC32, наконец, снова может сиять.
Вальф,

52

ОБНОВЛЕНИЕ : вышеуказанный вопрос и этот ответ относятся к 2015 году. С тех пор Google объявил о первом конфликте SHA-1: https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html


Очевидно, я могу только догадываться со стороны, глядя на то, почему Git продолжает использовать SHA-1, но это может быть одной из причин:

  1. Git был изобретением Линуса Торвальда, и Линус, очевидно, не хочет в настоящее время заменять SHA-1 другим алгоритмом хеширования.
  2. Он делает правдоподобные заявления о том, что успешные атаки на Git на основе коллизий SHA-1 намного сложнее, чем достижение самих коллизий, и, учитывая, что SHA-1 слабее, чем должен быть, не полностью сломан, что делает его существенно далеким от работоспособная атака по крайней мере сегодня. Более того, он отмечает, что «успешная» атака мало что даст, если сталкивающийся объект прибудет позже, чем существующий, поскольку более поздний объект будет просто предполагаться таким же, как действительный, и игнорироваться (хотя другие указывали, что могло произойти и обратное).
  3. Смена программного обеспечения требует времени и подвержена ошибкам, особенно при наличии существующей инфраструктуры и данных, основанных на существующих протоколах, которые необходимо перенести. Даже те, кто производит программные и аппаратные продукты, где криптографическая безопасность является единственной точкой системы, все еще находятся в процессе перехода от SHA-1 и других слабых алгоритмов местами. Только представьте себе, что все эти жестко запрограммированные unsigned char[20]буферы повсюду ;-), намного проще запрограммировать криптографическую гибкость в начале, чем модернизировать ее позже.
  4. Производительность SHA-1 лучше, чем у различных хэшей SHA-2 (вероятно, не настолько, чтобы быть препятствием для сделки сейчас, но, возможно, была камнем преткновения 10 лет назад), а размер хранилища SHA-2 больше .

Некоторые ссылки:

Мое личное мнение таково, что, хотя практические атаки, вероятно, когда-то отключены, и даже когда они действительно происходят, люди, вероятно, сначала будут смягчать их с помощью других средств, кроме изменения самого алгоритма хеширования, что, если вы действительно заботитесь о безопасности, вы должны ошибаться на стороне осторожности при выборе алгоритмов и постоянного пересмотра в сторону повышения ваших сильных сторон безопасности, потому что возможности злоумышленников также идут только в одном направлении, поэтому было бы неразумно использовать Git в качестве образца для подражания, особенно в качестве его цели в использование SHA-1 не претендует на криптографическую безопасность.


7
«У вас могут быть люди, которые пытаются быть злонамеренными. У них ничего не получится. N̶o̶b̶o̶d̶y̶ ̶h̶a̶s̶ ̶b̶e̶e̶n̶ ̶a̶b̶l̶e̶ ̶t̶o̶ ̶b̶r̶e̶a̶k̶ ̶S̶H̶A̶-̶1̶, но дело даже не в безопасности GA-1 . Это просто проверка согласованности ". -Линус Торвальдс
Шакти

9
Хэши Git должны быть безопасными для безопасных подписей, которые люди помещают в свой код для проверки чего-либо. Эти подписи подписывают огромное дерево этих хешей. Если какая-то ветвь этого дерева сталкивается, вредоносный код может быть вставлен во время прохождения сигнатуры. Git сейчас используется невероятно широко. Требуется обновление хэша.
fuzzyTew

Две вещи, которые следует учитывать в свете «разбитого»: 1. Использование SHA-1. - SHA-1 используется как прославленная контрольная сумма для проверки на случайное повреждение. - SHA-1 используется в качестве функции генератора для присвоения (несколько небольшого) удобного шестнадцатеричного числа для обозначения объектов внутри его адресуемого хранилища содержимого (то есть: прославленный генератор имен файлов). - Это подписанные коммиты, которые несут ответственность за безопасность (например: криптографическая сигнатура с открытым ключом. НЕ sha-1)
DrYak

2. Осуществимость - после кучи времени графического процессора Google удалось сгенерировать пару серий блоков. - оба хэша соответствуют одной и той же сумме SHA-1 (это коллизия) - они совершенно бесполезны (будет трудно оправдать, почему ваш коммит имеет гигантский блок двоичного мусора посередине). - разрушенная демонстрация полагается на способ представить различное поведение в зависимости от того, какой из случайных двоичных нежелательных файлов присутствует. Это возможно с PDF (за которым скрыт язык сценариев для встраивания). Это будет намного сложнее с открытым исходным кодом (подумайте о конкурсе Underhanded C)
DrYak

@DrYak Для 2: предположим, что вы отслеживаете документы фотошопа с полем комментария в них. Или другие медиафайлы с метатегами. Это типичный случай в разработке игр. Но обычно они не проверяются при каждом изменении: зачем проверять метатег, если в сообщении фиксации указано «оптимизировать по размеру»?
Arne Babenhauserheide

5

Это обсуждение срочности перехода от SHA1 к Mercurial, но это также относится и к Git: https://www.mercurial-scm.org/wiki/mpm/SHA1

Вкратце: если вы сегодня не очень прилежны, у вас гораздо более серьезные уязвимости, чем у sha1. Но, несмотря на это, Mercurial начал работу более 10 лет назад, чтобы подготовиться к переходу с sha1.

В течение многих лет велась работа по модернизации структур данных и протоколов Mercurial для преемников SHA1. Пространство для хранения было выделено для больших хэшей в нашей структуре журнала изменений более 10 лет назад в Mercurial 0.9 с появлением RevlogNG. Недавно представленный формат bundle2 поддерживает обмен различными типами хэшей по сети. Остается только выбрать функцию замены и стратегию обратной совместимости.

Если git не перейдет с sha1 раньше, чем это сделает Mercurial, вы всегда можете добавить еще один уровень безопасности, сохранив локальное зеркало Mercurial с помощью hg-git .


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.