J'ai lu que Git utilise le condensé SHA-1 comme ID pour une révision. Pourquoi n'utilise-t-il pas une version plus moderne de SHA?
J'ai lu que Git utilise le condensé SHA-1 comme ID pour une révision. Pourquoi n'utilise-t-il pas une version plus moderne de SHA?
Réponses:
Pourquoi n'utilise-t-il pas une version plus moderne de SHA?
Dec.2017: Ça le fera. Et Git 2.16 (Q1 2018) est la première version à illustrer et implémenter cette intention.
Remarque: voir Git 2.19 ci-dessous: ce sera SHA-256 .
Git 2.16 proposera une infrastructure pour définir quelle fonction de hachage est utilisée dans Git, et commencera un effort pour l'exploiter dans divers codepaths.
Voir commit c250e02 (28 novembre 2017) par Ramsay Jones (``) .
Voir commit eb0ccfd , commit 78a6766 , commit f50e766 , commit abade65 (12 novembre 2017) par brian m. carlson ( bk2204
) .
(Fusionné par Junio C Hamano - gitster
- in commit 721cc43 , 13 déc 2017)
Ajouter une structure représentant l'algorithme de hachage
Étant donné qu'à l'avenir, nous souhaitons prendre en charge un algorithme de hachage supplémentaire, ajouter une structure qui représente un algorithme de hachage et toutes les données qui doivent l'accompagner .
Ajoutez une constante pour permettre une énumération facile des algorithmes de hachage .
Implémentez une fonctiontypedefs
pour créer une API abstraite qui peut être utilisée par n'importe quel algorithme de hachage et des wrappers pour les fonctions SHA1 existantes conformes à cette API.Exposez une valeur pour la taille hexadécimale ainsi que la taille binaire .
Alors que l'un sera toujours le double de l'autre, les deux valeurs sont toutes deux utilisées de manière extrêmement courante dans toute la base de code et fournir les deux conduit à une meilleure lisibilité.N'incluez pas d'entrée dans la structure de l'algorithme de hachage pour l'ID d'objet nul.
Comme cette valeur est entièrement zéros, n'importe quel ID d'objet entièrement nul peut être utilisé, et il n'est pas nécessaire d'en stocker un par hachage.Le plan de transition de la fonction de hachage actuel envisage un moment où nous accepterons les entrées de l'utilisateur qui pourraient être au format SHA-1 ou au format NewHash.
Puisque nous ne pouvons pas savoir ce que l'utilisateur a fourni, ajoutez une constante représentant l'algorithme inconnu pour nous permettre d'indiquer que nous devons rechercher la valeur correcte.
Intégrer la prise en charge des algorithmes de hachage avec la configuration du dépôt
Dans les futures versions de Git, nous prévoyons de prendre en charge un algorithme de hachage supplémentaire.
Intégrez l'énumération des algorithmes de hachage à la configuration du référentiel et stockez un pointeur vers les données énumérées dans le référentiel struct .
Bien sûr, nous ne prenons actuellement en charge que SHA-1, donc codez en dur cette valeur dansread_repository_format
.
À l'avenir, nous énumérerons cette valeur à partir de la configuration.Ajoutez une constante,,
the_hash_algo
qui pointe vers lehash_algo
pointeur de structure dans le référentiel global.
Notez que c'est le hachage qui est utilisé pour sérialiser les données sur le disque, pas le hachage qui est utilisé pour afficher les éléments à l'utilisateur.
Le plan de transition prévoit que ceux-ci peuvent être différents.
Nous pouvons ajouter un élément supplémentaire à l'avenir (par exempleui_hash_algo
) pour prévoir ce cas.
Mise à jour d'août 2018, pour Git 2.19 (Q3 2018), Git semble choisir SHA-256 comme NewHash.
Voir commit 0ed8d8d (04 août 2018) par Jonathan Nieder ( artagnon
) .
Voir commit 13f5e09 (25 juillet 2018) par Ævar Arnfjörð Bjarmason ( avar
) .
(Fusionné par Junio C Hamano - gitster
- in commit 34f2297 , 20 août 2018)
doc
hash-function-transition
: choisissez SHA-256 comme NewHashDu point de vue de la sécurité, il semble que SHA-256, BLAKE2, SHA3-256, K12 et ainsi de suite aient tous des propriétés de sécurité similaires.
Ce sont toutes de bonnes options du point de vue de la sécurité.SHA-256 présente un certain nombre d'avantages:
Il existe depuis un certain temps, est largement utilisé et est pris en charge par à peu près toutes les bibliothèques de chiffrement (OpenSSL, mbedTLS, CryptoNG, SecureTransport, etc.).
Lorsque vous comparez avec SHA1DC, la plupart des implémentations SHA-256 vectorisées sont en effet plus rapides, même sans accélération.
Si nous faisons des signatures avec OpenPGP (ou même, je suppose, CMS), nous allons utiliser SHA-2, il n'est donc pas logique que notre sécurité dépende de deux algorithmes séparés lorsque l'un d'entre eux seul pourrait briser la sécurité alors que nous ne pouvions compter que sur un seul.
C'est donc SHA-256 .
Mettez à jour le document de conception de transition de fonction de hachage pour le dire.Après ce patch, il n'y a plus d'instances restantes de la chaîne "
NewHash
", à l'exception d'une utilisation non liée à partir de 2008 comme nom de variable danst/t9700/test.pl
.
Vous pouvez voir cette transition vers SHA 256 en cours avec Git 2.20 (Q4 2018):
Voir commettre 0d7c419 , engager dda6346 , engager eccb5a5 , engager 93eb00f , engager d8a3a69 , engager fbd0e37 , engager f690b6b , engager 49d1660 , engager 268babd , engager fa13080 , engager 7b5e614 , engager 58ce21b , engager 2f0c9e9 , engager 825544a (15 octobre 2018) par brian m . carlson ( bk2204
) .
Voir commit 6afedba (15 octobre 2018) par SZEDER Gábor ( szeder
) .
(Fusionné parJunio C Hamano - gitster
- dans commit d829d49 , 30 octobre 2018)
remplacer les constantes codées en dur
Remplacez plusieurs constantes de base 40 par des références à
GIT_MAX_HEXSZ
outhe_hash_algo
, selon le cas.
Convertissez toutes les utilisations deGIT_SHA1_HEXSZ
à utiliserthe_hash_algo
afin qu'elles soient appropriées pour une longueur de hachage donnée.
Au lieu d'utiliser une constante codée en dur pour la taille d'un ID d'objet hexadécimal, basculez pour utiliser le pointeur calculé à partir deparse_oid_hex
ces points après l'ID d'objet analysé.
GIT_SHA1_HEXSZ
est en outre supprimé / remplacé par Git 2.22 (Q2 2019) et commit d4e568b .
Cette transition se poursuit avec Git 2.21 (Q1 2019), qui ajoute le hachage sha-256 et le branche via le code pour permettre la construction de Git avec le "NewHash".
Voir engager 4b4e291 , engager 27dc04c , engager 13eeedb , engager c166599 , engager 37649b7 , engager a2ce0a7 , engager 50c817e , engager 9a3a0ff , engager 0dab712 , engager 47edb64 (14 novembre 2018), et engager 2f90b9d , engager 1ccf07c (22 octobre 2018) par Brian m . carlson ( bk2204
) .
(Fusionné par Junio C Hamano - gitster
- dans commit 33e4ae9 , 29 janvier 2019)
Ajouter une implémentation de base du support SHA-256 (février 2019)
SHA-1 est faible et nous devons passer à une nouvelle fonction de hachage.
Depuis quelque temps, nous avons appelé cette nouvelle fonctionNewHash
.
Récemment, nous avons décidé de choisir SHA-256 commeNewHash
.
Les raisons du choix de SHA-256 sont décrites dans ce fil et dans l'historique des validations pour le document de transition de fonction de hachage.Ajoutez une implémentation de base de SHA-256 basée sur
libtomcrypt
, qui est dans le domaine public.
Optimisez-le et restructurez-le pour répondre à nos normes de codage.
Tirez la mise à jour et les fonctions finales de l'implémentation du bloc SHA-1, car nous savons qu'elles fonctionnent correctement avec tous les compilateurs. Cette implémentation est plus lente que SHA-1, mais des implémentations plus performantes seront introduites dans les commits futurs.Connectez SHA-256 dans la liste des algorithmes de hachage et ajoutez un test indiquant que l'algorithme fonctionne correctement.
Notez qu'avec ce patch, il n'est toujours pas possible de passer à l'utilisation de SHA-256 dans Git.
Des correctifs supplémentaires sont nécessaires pour préparer le code afin de gérer un algorithme de hachage plus volumineux et d'autres correctifs de test sont nécessaires.
hash
: ajouter une implémentation SHA-256 en utilisant OpenSSLNous avons déjà des routines OpenSSL disponibles pour SHA-1, alors ajoutez également des routines pour SHA-256.
Sur un Core i7-6600U, cette implémentation SHA-256 se compare favorablement à l'implémentation 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
: ajoutez une implémentation SHA-256 en utilisantlibgcrypt
En général, les routines cryptographiques écrites en assemblage sont plus performantes que C, et cela est également vrai pour SHA-256.
De plus, la plupart des distributions Linux ne peuvent pas distribuer Git lié à OpenSSL pour des raisons de licence.La plupart des systèmes avec GnuPG en auront également
libgcrypt
, car il s'agit d'une dépendance de GnuPG.
libgcrypt
est également plus rapide que l'implémentation SHA1DC pour les messages de quelques Ko et plus.À titre de comparaison, sur un Core i7-6600U, cette implémentation traite 16 blocs de Kio à 355 Mio / s tandis que SHA1DC traite des morceaux équivalents à 337 Mio / s.
En outre, libgcrypt est sous licence LGPL 2.1, qui est compatible avec la GPL. Ajoutez une implémentation de SHA-256 qui utilise libgcrypt.
L'effort de mise à niveau se poursuit avec Git 2.24 (T4 2019)
Voir commit aaa95df , commit be8e172 , commit 3f34d70 , commit fc06be3 , commit 69fa337 , commit 3a4d7aa , commit e0cb7cd , commit 8d4d86b , commit f6ca67d , commit dd336a5 , commit 894c0f6 , commit 4439c7a , commit e0cb7cd , commit 8d4d86b , commit f6ca67d , commit dd336a5 , commit 894c0f6 , commit 4439c7a , commit e0cb7cd , commit 8d4d86b , commit f6ca67d , commit dd336a5 , commit 894c0f6 , commit 4439c7a , commit e0cb7cd , commit 8d4d86b , commit f6ca67d , commit dd336a5 , commit 894c0f6 , commit 4439c7a , commit 95518fa , commite 703d2d4 , validation 9d958cc , validation 7962e04 , frais de validation 4930(18 août 2019) par brian m. carlson ( bk2204
) .
(Fusionné par Junio C Hamano - gitster
- dans commit 676278f , 11 octobre 2019)
Au lieu d'utiliser
GIT_SHA1_HEXSZ
des constantes codées en dur, passez à usingthe_hash_algo
.
Avec Git 2.26 (Q1 2020), les scripts de test sont prêts pour le jour où les noms d'objets utiliseront SHA-256.
Voir commettre 277eb5a , engager 44b6c05 , engager 7a868c5 , engager 1b8f39f , engager a8c17e3 , engager 8.320.722 , engager 74ad99b , engager ba1be1a , engager cba472d , engager 82d5aeb , engager 3c5e65c , engager 235d3cd , engager 1d86c8f , engager 525a7f1 , engager 7a1bcb2 , engager cb78f4f , commit 717c939 , commit 08a9dd8 , commit 215b60b , commit 194264c(21 décembre 2019) par brian m. carlson ( bk2204
) .
(Fusionné par Junio C Hamano - gitster
- in commit f52ab33 , 05 fév 2020)
Exemple:
t4204
: rendre la taille de hachage indépendanteSigné par: Brian M. Carlson
À utiliser
$OID_REGEX
au lieu d'une expression régulière codée en dur.
Donc, au lieu d'utiliser:
grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
Les tests utilisent
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
Et OID_REGEX
vient du commit bdee9cd (13 mai 2018) par brian m. carlson ( bk2204
) .
(Fusionné par Junio C Hamano - gitster
- dans commit 9472b13 , 30 mai 2018, Git v2.18.0-rc0)
t/test-lib
: présenterOID_REGEX
Signé par: Brian M. Carlson
Actuellement, nous avons une variable,
$_x40,
qui contient une expression régulière qui correspond à une constante hexadécimale de 40 caractères.Cependant, avec
NewHash
, nous aurons des ID d'objet de plus de 40 caractères.Dans un tel cas,
$_x40
sera un nom déroutant.Créez une
$OID_REGEX
variable qui reflétera toujours une expression régulière correspondant à l'ID d'objet approprié, quelle que soit la longueur du hachage actuel.
Et, toujours pour les tests:
Voir commettre f303765 , engager edf0424 , engager 5db24dc , engager d341e08 , engager 88ed241 , engager 48c10cc , engager f7ae8e6 , commettre e70649b , commettre a30f93b , commettre a79eec2 , engager 796d138 , engager 417e45e , engager dfa5f53 , engager f743e8f , engager 72f936b , engager 5df0f11 , commit 07877f3 , commit 6025e89 , commit 7b1a182 , commit 94db7e3 ,commit db12505 (07 févr.2020 ) par brian m. carlson ( bk2204
) .
(Fusionné par Junio C Hamano - gitster
- in commit 5af345a , 17 fév 2020)
t5703
: faire fonctionner le test avec SHA-256Signé par: Brian M. Carlson
Ce test a utilisé un ID d'objet d'une longueur de 40 caractères hexadécimaux, ce qui a non seulement fait en sorte que le test ne réussisse pas, mais qu'il se bloque, lorsqu'il est exécuté avec SHA-256 comme hachage.
Remplacez cette valeur par un ID d'objet factice fixe à l'aide de
test_oid_init
ettest_oid
.De plus, assurez-vous d'extraire un ID d'objet de la longueur appropriée en utilisant une coupe avec des champs au lieu d'une longueur fixe.
Certains codepaths ont reçu une instance de référentiel en tant que paramètre pour fonctionner dans le référentiel, mais ont passé l' the_repository
instance à ses appelées, qui a été nettoyée (un peu) avec Git 2.26 (Q1 2020).
Voir commit b98d188 , commit 2dcde20 , commit 7ad5c44 , commit c8123e7 , commit 5ec9b8a , commit a651946 , commit eb999b3 (30 janvier 2020) par Matheus Tavares ( matheustavares
) .
(Fusionné par Junio C Hamano - gitster
- dans commit 78e67cd , 14 février 2020)
sha1-file
: permetcheck_object_signature()
de gérer n'importe quel repoSigné par: Matheus Tavares
Certains appelants de
check_object_signature()
peuvent travailler sur des référentiels arbitraires, mais le référentiel n'est pas passé à cette fonction. Au lieu de cela,the_repository
est toujours utilisé en interne.
Pour corriger d'éventuelles incohérences, autorisez la fonction à recevoir un référentiel struct et faites en sorte que ces appelants transmettent le référentiel en cours de traitement.
Basé sur:
sha1-file
: passergit_hash_algo
àhash_object_file()
Signé par: Matheus Tavares
Permet
hash_object_file()
de travailler sur des dépôts arbitraires en introduisant ungit_hash_algo
paramètre. Changez les appelants qui ont un pointeur de référentiel struct dans leur portée pour transmettre legit_hash_algo
depuis ledit dépôt.
Pour tous les autres appelants, transmettrethe_hash_algo
, qui était déjà utilisé en interne àhash_object_file()
.
Cette fonctionnalité sera utilisée dans le patch suivant pourcheck_object_signature()
pouvoir travailler sur des dépôts arbitraires (qui, à son tour, seront utilisés pour corriger une incohérence au niveau deobject.c
: parse_object ()).
git rev-parse
est maintenant capable d'imprimer quel hachage sera utilisé: stackoverflow.com/a/58862319/6309 . Et l'arbre vide a un nouvel identifiant SHA2: stackoverflow.com/a/9766506/6309
MISE À JOUR : La question ci-dessus et cette réponse datent de 2015. Depuis lors, Google a annoncé la première collision SHA-1: https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
Évidemment, je ne peux que spéculer de l'extérieur en regardant pourquoi Git continue d'utiliser SHA-1, mais cela peut être l'une des raisons:
unsigned char[20]
tampons codés en dur partout ;-), il est beaucoup plus facile de programmer l'agilité cryptographique au début, plutôt que de le moderniser plus tard.Quelques liens:
Mon point de vue personnel serait que, même si les attaques pratiques sont probablement un certain temps, et même lorsqu'elles se produisent, les gens les atténueront probablement au départ avec des moyens autres que de changer l'algorithme de hachage lui-même, que si vous vous souciez de la sécurité, vous devriez vous tromper. du côté de la prudence dans vos choix d'algorithmes, et en révisant continuellement à la hausse vos forces de sécurité, car les capacités des attaquants ne vont également que dans une direction, il serait donc imprudent de prendre Git comme modèle, d'autant plus que son objectif dans l'utilisation de SHA-1 ne prétend pas être une sécurité cryptographique.
Ceci est une discussion sur l'urgence de migrer loin de SHA1 pour Mercurial, mais cela s'applique également à Git: https://www.mercurial-scm.org/wiki/mpm/SHA1
En bref: si vous n'êtes pas extrêmement intelligent aujourd'hui, vous avez des vulnérabilités bien pires que sha1. Mais malgré cela, Mercurial a commencé il y a plus de 10 ans à se préparer à migrer loin de sha1.
des travaux sont en cours depuis des années pour moderniser les structures de données et les protocoles de Mercurial pour les successeurs de SHA1. L'espace de stockage a été alloué pour des hachages plus importants dans notre structure de revlog il y a plus de 10 ans dans Mercurial 0.9 avec l'introduction de RevlogNG. Le format bundle2 introduit plus récemment prend en charge l'échange de différents types de hachage sur le réseau. Les seules pièces restantes sont le choix d'une fonction de remplacement et le choix d'une stratégie de rétrocompatibilité.
Si git ne migre pas de sha1 avant Mercurial, vous pouvez toujours ajouter un autre niveau de sécurité en gardant un miroir Mercurial local avec hg-git .
Il existe maintenant un plan de transition vers un hachage plus fort, il semble donc qu'à l'avenir, il utilisera un hachage plus moderne que SHA-1. À partir du plan de transition actuel :
Certains hachages considérés sont SHA-256, SHA-512/256, SHA-256x16, K12 et BLAKE2bp-256