Leí sobre que Git usa SHA-1 digest como ID para una revisión. ¿Por qué no usa una versión más moderna de SHA?
Leí sobre que Git usa SHA-1 digest como ID para una revisión. ¿Por qué no usa una versión más moderna de SHA?
Respuestas:
¿Por qué no usa una versión más moderna de SHA?
Diciembre de 2017: lo hará. Y Git 2.16 (Q1 2018) es la primera versión para ilustrar e implementar esa intención.
Nota: consulte Git 2.19 a continuación: será SHA-256 .
Git 2.16 propondrá una infraestructura para definir qué función hash se usa en Git y comenzará un esfuerzo para sondear eso a través de varias rutas de código.
Consulte la confirmación c250e02 (28 de noviembre de 2017) de Ramsay Jones (``) .
Consulte commit eb0ccfd , commit 78a6766 , commit f50e766 , commit abade65 (12 de noviembre de 2017) por brian m. carlson ( bk2204
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 721cc43 , 13 de diciembre de 2017)
Agregar estructura que represente el algoritmo hash
Dado que en el futuro queremos admitir un algoritmo hash adicional, agregue una estructura que represente un algoritmo hash y todos los datos que deben acompañarlo .
Agregue una constante para permitir una fácil enumeración de algoritmos hash .
Implemente la funcióntypedefs
para crear una API abstracta que pueda ser utilizada por cualquier algoritmo hash y envoltorios para las funciones SHA1 existentes que se ajusten a esta API.Exponga un valor para el tamaño hexadecimal y el tamaño binario .
Si bien uno siempre será el doble del otro, los dos valores se usan con mucha frecuencia en toda la base de código y proporcionan ambos resultados para mejorar la legibilidad.No incluya una entrada en la estructura del algoritmo hash para el ID de objeto nulo.
Como este valor es todo ceros, se puede utilizar cualquier ID de objeto todo cero de tamaño adecuado, y no es necesario almacenar uno determinado por hash.El plan de transición de la función hash actual prevé un momento en el que aceptaremos la entrada del usuario que podría estar en SHA-1 o en el formato NewHash.
Dado que no podemos saber cuál ha proporcionado el usuario, agregue una constante que represente el algoritmo desconocido para permitirnos indicar que debemos buscar el valor correcto.
Integrar el soporte del algoritmo hash con la configuración del repositorio
En futuras versiones de Git, planeamos admitir un algoritmo hash adicional.
Integre la enumeración de algoritmos hash con la configuración del repositorio y almacene un puntero a los datos enumerados en el repositorio de estructura .
Por supuesto, actualmente solo admitimos SHA-1, así que codifique este valor enread_repository_format
.
En el futuro, enumeraremos este valor de la configuración.Agregue una constante,
the_hash_algo
que apunta alhash_algo
puntero de estructura en el repositorio global.
Tenga en cuenta que este es el hash que se usa para serializar datos en el disco, no el hash que se usa para mostrar elementos al usuario.
El plan de transición anticipa que estos pueden ser diferentes.
Podemos agregar un elemento adicional en el futuro (digamos,ui_hash_algo
) para proporcionar este caso.
Actualización de agosto de 2018, para Git 2.19 (Q3 2018), Git parece elegir SHA-256 como NewHash.
Consulte la confirmación 0ed8d8d (4 de agosto de 2018) de Jonathan Nieder ( artagnon
) .
Consulte la confirmación 13f5e09 (25 de julio de 2018) de Ævar Arnfjörð Bjarmason ( avar
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 34f2297 , 20 de agosto de 2018)
doc
hash-function-transition
: elija SHA-256 como NewHashDesde una perspectiva de seguridad, parece que se cree que SHA-256, BLAKE2, SHA3-256, K12, etc. tienen propiedades de seguridad similares.
Todas son buenas opciones desde el punto de vista de la seguridad.SHA-256 tiene una serie de ventajas:
Ha existido por un tiempo, se usa ampliamente y es compatible con casi todas las bibliotecas de cifrado (OpenSSL, mbedTLS, CryptoNG, SecureTransport, etc.).
Cuando se compara con SHA1DC, la mayoría de las implementaciones de SHA-256 vectorizadas son de hecho más rápidas, incluso sin aceleración.
Si estamos haciendo firmas con OpenPGP (o incluso, supongo, CMS), usaremos SHA-2, por lo que no tiene sentido que nuestra seguridad dependa de dos algoritmos separados cuando cualquiera de ellos solo podría romper la seguridad cuando solo podíamos depender de uno.
Entonces SHA-256 lo es .
Actualice el documento de diseño de transición de función hash para indicarlo.Después de este parche, no quedan instancias de la cadena "
NewHash
", excepto por un uso no relacionado de 2008 como nombre de variable ent/t9700/test.pl
.
Puede ver esta transición a SHA 256 en progreso con Git 2.20 (Q4 2018):
Ver cometer 0d7c419 , cometer dda6346 , cometer eccb5a5 , cometer 93eb00f , cometer d8a3a69 , cometer fbd0e37 , cometer f690b6b , cometer 49d1660 , cometer 268babd , cometer fa13080 , cometer 7b5e614 , cometer 58ce21b , cometer 2f0c9e9 , cometer 825544a (15 Oct 2018) por Brian m . carlson ( bk2204
) .
Véase el compromiso 6afedba (15 de octubre de 2018) de SZEDER Gábor ( szeder
) .
(Fusionada porJunio C Hamano - gitster
- en el compromiso d829d49 , 30 de octubre de 2018)
reemplazar constantes codificadas de forma rígida
Reemplace varias constantes basadas en 40 con referencias a
GIT_MAX_HEXSZ
othe_hash_algo
, según corresponda.
Convierta todos los usos delGIT_SHA1_HEXSZ
a usar dethe_hash_algo
modo que sean apropiados para cualquier longitud de hash dada.
En lugar de utilizar una constante codificada de forma rígida para el tamaño de un ID de objeto hexadecimal, cambie para usar el puntero calculado desdeparse_oid_hex
esos puntos después del ID de objeto analizado.
GIT_SHA1_HEXSZ
se elimina / reemplaza con Git 2.22 (Q2 2019) y confirma d4e568b .
Esa transición continúa con Git 2.21 (Q1 2019), que agrega hash sha-256 y lo conecta a través del código para permitir la construcción de Git con el "NewHash".
Ver cometer 4b4e291 , cometer 27dc04c , cometer 13eeedb , cometer c166599 , cometer 37649b7 , cometer a2ce0a7 , cometer 50c817e , cometer 9a3a0ff , cometer 0dab712 , cometer 47edb64 (14 Nov 2018), y comprometerse 2f90b9d , cometer 1ccf07c (22 Oct 2018) por Brian m . carlson ( bk2204
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 33e4ae9 , 29 de enero de 2019)
Agregar una implementación base de compatibilidad con SHA-256 (febrero de 2019)
SHA-1 es débil y necesitamos hacer la transición a una nueva función hash.
Durante algún tiempo, nos hemos referido a esta nueva función comoNewHash
.
Recientemente, decidimos elegir SHA-256 comoNewHash
.
Las razones detrás de la elección de SHA-256 se describen en este hilo y en el historial de confirmación para el documento de transición de la función hash.Agregue una implementación básica de SHA-256 basada en
libtomcrypt
, que es de dominio público.
Optimizarlo y reestructurarlo para cumplir con nuestros estándares de codificación.
Extraiga las funciones de actualización y final de la implementación del bloque SHA-1, ya que sabemos que funcionan correctamente con todos los compiladores. Esta implementación es más lenta que SHA-1, pero se introducirán implementaciones de mayor rendimiento en futuras confirmaciones.Conecte SHA-256 en la lista de algoritmos hash y agregue una prueba de que el algoritmo funciona correctamente.
Tenga en cuenta que con este parche, todavía no es posible cambiar al uso de SHA-256 en Git.
Se necesitan parches adicionales para preparar el código para manejar un algoritmo hash más grande y se necesitan más correcciones de prueba.
hash
: agregue una implementación SHA-256 usando OpenSSLYa tenemos rutinas OpenSSL disponibles para SHA-1, así que agregue rutinas para SHA-256 también.
En un Core i7-6600U, esta implementación SHA-256 se compara favorablemente con la implementación 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
: agregue una implementación SHA-256 usandolibgcrypt
Generalmente, se obtiene un mejor rendimiento de las rutinas criptográficas escritas en ensamblador que C, y esto también es cierto para SHA-256.
Además, la mayoría de las distribuciones de Linux no pueden distribuir Git vinculado contra OpenSSL por motivos de licencia.La mayoría de los sistemas con GnuPG también lo tendrán
libgcrypt
, ya que es una dependencia de GnuPG.
libgcrypt
también es más rápido que la implementación de SHA1DC para mensajes de unos pocos KiB o más.A modo de comparación, en un Core i7-6600U, esta implementación procesa fragmentos de 16 KiB a 355 MiB / s, mientras que SHA1DC procesa fragmentos equivalentes a 337 MiB / s.
Además, libgcrypt tiene licencia LGPL 2.1, que es compatible con la GPL. Agregue una implementación de SHA-256 que usa libgcrypt.
El esfuerzo de actualización continúa con Git 2.24 (Q4 2019)
Ver cometer aaa95df , comprometerse be8e172 , comprometerse 3f34d70 , comprometerse fc06be3 , comprometerse 69fa337 , comprometerse 3a4d7aa , comprometerse e0cb7cd , comprometerse 8d4d86b , comprometerse f6ca67d , comprometerse dd336a5 , cometen 894c0f6 , comprometerse 4439c7a , comprometerse 95518fa , comprometerse e84f357 , comprometerse fe9fec4 , comprometerse 976ff7e , cometen 703d2d4 , cometer 9d958cc , cometer 7962e04 , cometer fee4930(18 de ago de 2019) de brian m. carlson ( bk2204
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 676278f , 11 de octubre de 2019)
En lugar de usar
GIT_SHA1_HEXSZ
y constantes codificadas de forma rígida, cambie a usingthe_hash_algo
.
Con Git 2.26 (Q1 2020), los scripts de prueba están listos para el día en que los nombres de los objetos usen SHA-256.
Ver cometer 277eb5a , comprometerse 44b6c05 , comprometerse 7a868c5 , comprometerse 1b8f39f , comprometerse a8c17e3 , comprometerse 8.320.722 , comprometerse 74ad99b , comprometerse ba1be1a , comprometerse cba472d , comprometerse 82d5aeb , comprometerse 3c5e65c , comprometerse 235d3cd , comprometerse 1d86c8f , comprometerse 525a7f1 , comprometerse 7a1bcb2 , comprometerse cb78f4f , cometen 717c939 , confirma 08a9dd8 , confirma 215b60b , confirma 194264c(21 de diciembre de 2019) de brian m. carlson ( bk2204
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso f52ab33 , 05 de febrero de 2020)
Ejemplo:
t4204
: hacer que el tamaño del hash sea independienteFirmado por: brian m. carlson
Úselo en
$OID_REGEX
lugar de una expresión regular codificada.
Entonces, en lugar de usar:
grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
Las pruebas están usando
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
Y OID_REGEX
proviene de commit bdee9cd (13 de mayo de 2018) de brian m. carlson ( bk2204
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 9472b13 , 30 de mayo de 2018, Git v2.18.0-rc0)
t/test-lib
: introducirOID_REGEX
Firmado por: brian m. carlson
Actualmente tenemos una variable,
$_x40,
que contiene una expresión regular que coincide con una constante hexadecimal completa de 40 caracteres.Sin embargo, con
NewHash
, tendremos identificadores de objetos de más de 40 caracteres.En tal caso,
$_x40
será un nombre confuso.Cree una
$OID_REGEX
variable que siempre refleje una expresión regular que coincida con el ID de objeto apropiado, independientemente de la longitud del hash actual.
Y, todavía para las pruebas:
Ver cometer f303765 , comprometerse edf0424 , comprometerse 5db24dc , cometen d341e08 , comprometerse 88ed241 , comprometerse 48c10cc , comprometerse f7ae8e6 , cometen e70649b , cometen a30f93b , cometen a79eec2 , comprometerse 796d138 , comprometerse 417e45e , comprometerse dfa5f53 , comprometerse f743e8f , cometen 72f936b , comprometerse 5df0f11 , cometen 07877f3 , confirma 6025e89 , confirma 7b1a182 , confirma 94db7e3 ,commit db12505 (07 de febrero de 2020) por brian m. carlson ( bk2204
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 5af345a , 17 de febrero de 2020)
t5703
: hacer que la prueba funcione con SHA-256Firmado por: brian m. carlson
Esta prueba utilizó un ID de objeto que tenía 40 caracteres hexadecimales de longitud, lo que provocó que la prueba no solo no pasara, sino que se bloqueara cuando se ejecutaba con SHA-256 como hash.
Cambie este valor a un ID de objeto ficticio fijo usando
test_oid_init
ytest_oid
.Además, asegúrese de extraer un ID de objeto de la longitud adecuada utilizando cortar con campos en lugar de una longitud fija.
Algunas rutas de código recibieron una instancia de repositorio como parámetro para trabajar en el repositorio, pero pasaron la the_repository
instancia a sus destinatarios, que se ha limpiado (algo) con Git 2.26 (Q1 2020).
Consulte confirmar b98d188 , confirmar 2dcde20 , confirmar 7ad5c44 , confirmar c8123e7 , confirmar 5ec9b8a , confirmar a651946 , confirmar eb999b3 (30 de enero de 2020) por Matheus Tavares ( matheustavares
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 78e67cd , 14 de febrero de 2020)
sha1-file
: permitecheck_object_signature()
manejar cualquier repositorioFirmado por: Matheus Tavares
Algunas personas que llaman a
check_object_signature()
pueden trabajar en repositorios arbitrarios, pero el repositorio no se pasa a esta función. En cambio,the_repository
siempre se usa internamente.
Para corregir posibles inconsistencias, permita que la función reciba un repositorio de estructura y haga que los llamadores pasen el repositorio que se está manejando.
Residencia en:
sha1-file
: pasargit_hash_algo
ahash_object_file()
Firmado por: Matheus Tavares
Permitir
hash_object_file()
trabajar en repositorios arbitrarios introduciendo ungit_hash_algo
parámetro. Cambie las personas que llaman que tienen un puntero de repositorio de estructura en su alcance para pasar elgit_hash_algo
desde dicho repositorio.
Para todas las demás personas que llaman, pasethe_hash_algo
, que ya se estaba utilizando internamente enhash_object_file()
.
Esta funcionalidad se utilizará en el siguiente parche paracheck_object_signature()
poder trabajar en repositorios arbitrarios (que, a su vez, se utilizará para corregir una inconsistencia enobject.c
: parse_object ()).
git rev-parse
ahora puede imprimir qué hash se utilizará: stackoverflow.com/a/58862319/6309 . Y el árbol vacío tiene una nueva identificación SHA2: stackoverflow.com/a/9766506/6309
ACTUALIZACIÓN : La pregunta anterior y esta respuesta son de 2015. Desde entonces, Google ha anunciado la primera colisión SHA-1: https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
Obviamente, solo puedo especular desde afuera mirando hacia adentro sobre por qué Git continúa usando SHA-1, pero estas pueden ser algunas de las razones:
unsigned char[20]
búferes codificados por todas partes ;-), es mucho más fácil programar para agilidad criptográfica al principio, en lugar de actualizarlo más tarde.Algunos enlaces:
Mi opinión personal sería que, si bien los ataques prácticos probablemente están fuera de su alcance, e incluso cuando ocurren, las personas probablemente inicialmente los mitigarán con otros medios que no sean cambiar el algoritmo hash en sí, que si a usted le importa la seguridad, debería estar errando. por el lado de la precaución con sus elecciones de algoritmos, y revisando continuamente hacia arriba sus fortalezas de seguridad, porque las capacidades de los atacantes también van solo en una dirección, por lo que no sería prudente tomar a Git como un modelo a seguir, especialmente como su propósito en el uso de SHA-1 no pretende ser seguridad criptográfica.
Esta es una discusión sobre la urgencia de migrar desde SHA1 para Mercurial, pero también se aplica a Git: https://www.mercurial-scm.org/wiki/mpm/SHA1
En resumen: si no eres extremadamente diligente hoy, tienes vulnerabilidades mucho peores que sha1. Pero a pesar de eso, Mercurial comenzó hace más de 10 años a prepararse para migrar desde sha1.
Se ha trabajado durante años para adaptar las estructuras de datos y los protocolos de Mercurial para los sucesores de SHA1. El espacio de almacenamiento se asignó para hashes más grandes en nuestra estructura de revlog hace más de 10 años en Mercurial 0.9 con la introducción de RevlogNG. El formato bundle2 introducido más recientemente admite el intercambio de diferentes tipos de hash a través de la red. Las únicas piezas restantes son la elección de una función de reemplazo y la elección de una estrategia de compatibilidad con versiones anteriores.
Si git no migra de sha1 antes que Mercurial, siempre puede agregar otro nivel de seguridad manteniendo un espejo Mercurial local con hg-git .
Ahora hay un plan de transición a un hash más fuerte, por lo que parece que en el futuro utilizará un hash más moderno que SHA-1. Del plan de transición actual :
Algunos hash que se están considerando son SHA-256, SHA-512/256, SHA-256x16, K12 y BLAKE2bp-256