Чому 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 07

28
Оновлення: зіткнення SHA-1 зараз у дикій природі shattered.it
drawwr

2
1-й квартал 2018: ця спроба підтримати альтернативний SHA триває: див. Мою відповідь нижче
VonC

Відповіді:


62

Чому в ньому не використовується більш сучасна версія SHA?

Грудень 2017: Буде. А Git 2.16 (Q1 2018) - це перший випуск, який ілюструє та реалізує цей намір.

Примітка: див. Git 2.19 нижче: це буде SHA-256 .

Git 2.16 запропонує інфраструктуру, щоб визначити, яка хеш-функція використовується в Git, і розпочне спроби виправити це через різні кодові шляхи.

Див. Коміт c250e02 (28 листопада 2017 р.) Рамзі Джонса (``) .
Див. Коміт eb0ccfd , коміт 78a6766 , коміт f50e766 , коміт abade65 (12 листопада 2017 р.) Брайан М. Карлсон ( 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вказівник на структуру в глобальному сховищі.
Зверніть увагу, що це хеш, який використовується для серіалізації даних на диск, а не хеш, який використовується для відображення елементів користувачеві.
План переходу передбачає, що вони можуть бути різними.
Ми можемо додати додатковий елемент у майбутньому (скажімо, ui_hash_algo) для забезпечення цього випадку.


Оновлення в серпні 2018 року, для Git 2.19 (Q3 2018), схоже, Git вибирає SHA-256 як NewHash.

Див. Коміт 0ed8d8d (04 серпня 2018 р.) Джонатана Нідера ( artagnon) .
Див. Коміт 13f5e09 (25 липня 2018 р.) Від Ævar Arnfjörð Bjarmason ( avar) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 34f2297 , 20 серпня 2018)

dochash-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 (Q4 2018):

Див здійснюють 0d7c419 , здійснює dda6346 , здійснює eccb5a5 , здійснює 93eb00f , здійснює d8a3a69 , здійснюють fbd0e37 , здійснює f690b6b , здійснює 49d1660 , здійснює 268babd , здійснює fa13080 , здійснює 7b5e614 , здійснюють 58ce21b , здійснює 2f0c9e9 , здійснює 825544a (15 жовтня 2018) по Брайан м . Карлсон ( bk2204) .
Див. Коміт 6afedba (15 жовтня 2018 р.) Від SZEDER Gábor ( 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 (Q2 2019) і зафіксувати d4e568b .


Цей перехід триває з Git 2.21 (Q1 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, яка знаходиться у відкритому доступі.
Оптимізуйте його та реструктуруйте відповідно до наших стандартів кодування.
Витягніть функції оновлення та остаточну функцію з реалізації блоку 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 (Q4 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констант з жорстким кодом, перейдіть на використання 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 , 05 лютого 2020)

Приклад:

t4204: зробити незалежний розмір хешу

Підписав: Брайан М. Карлсон

Використовуйте $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 р.) Брайана М. Карлсон ( bk2204) .
(Об’єднано Junio ​​C Hamano - gitster- у коміті 9472b13 , 30 травня 2018 р., Git v2.18.0-rc0)

t/test-lib: ввести OID_REGEX

Підписав: Брайан М. Карлсон

На даний момент ми маємо змінну, $_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 ,коміт db12505 (07 лютого 2020), Брайан М. Карлсон ( bk2204) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 5af345a , 17 лютого 2020)

t5703: зробити тестову роботу з SHA-256

Підписав: Брайан М. Карлсон

У цьому тесті було використано ідентифікатор об’єкта довжиною 40 шістнадцяткових символів, що призвело до того, що тест не тільки не пройшов, але і завис при запуску з SHA-256 як хеш.

Змініть це значення на фіксований фіктивний ідентифікатор об'єкта, використовуючи test_oid_initта test_oid.

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


Деякі кодові шляхи отримали екземпляр сховища як параметр для роботи в сховищі, але передали the_repositoryекземпляр його викликам, що було очищено (дещо) за допомогою Git 2.26 (Q1 2020).

Див здійснювати b98d188 , здійснювати 2dcde20 , здійснюють 7ad5c44 , здійснюють c8123e7 , здійснюють 5ec9b8a , здійснюють a651946 , здійснюють eb999b3 (30 січня 2020) по Matheus Таварес ( matheustavares) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 78e67cd , 14 лютого 2020)

sha1-file: дозволити check_object_signature()обробляти будь-які репо

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

Деякі абоненти check_object_signature()можуть працювати з довільними сховищами, але репо не передається цій функції. Натомість the_repositoryзавжди використовується внутрішньо.
Щоб виправити можливі невідповідності, дозвольте функції отримувати репозиторій struct і змусити цих абонентів передати репо, яке обробляється.

На основі:

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 ID: 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. Він висловлює правдоподібні твердження, що успішні атаки на основі зіткнень SHA-1 проти Git набагато складніше, ніж досягнення самих зіткнень, і враховуючи, що 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̶, але справа тут навіть не в тому, Це суто перевірка узгодженості ". -Лінус Торвальдс
Шакті

9
Хеш Git повинен бути захищений для безпечних підписів, які люди розміщують у своєму коді, щоб щось перевірити. Ці підписи підписують величезне дерево цих хешів. Якщо якась гілка цього дерева зіштовхується, під час проходження підпису може бути вставлений зловмисний код. Зараз Git використовується неймовірно широко. Потрібне оновлення хешу.
fuzzyTew

Дві речі, які слід врахувати у світлі "розбитого": 1. Використання SHA-1. - SHA-1 використовується як прославлена ​​контрольна сума для перевірки на випадкові корупції. - SHA-1 використовується як функція генератора, щоб надати (дещо невелике) зручне шістнадцяткове число для позначення об'єктів у своєму адресному сховищі вмісту (тобто: прославлений генератор імен файлів). - Це підписані коміти, які відповідають за безпеку (тобто: підпис криптографії з відкритим ключем. НЕ sha-1)
DrYak

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

@DrYak Для 2: припустимо, що ви відстежуєте документи Photoshop із полем коментарів. Або інші мультимедійні файли з мета-тегами. Це типовий випадок у розробці ігор. Але їх зазвичай не перевіряють при кожній зміні: навіщо перевіряти мета-тег, якщо в повідомленні коміту написано "оптимізувати за розміром"?
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.