tag remove practices crear best git cryptography sha

remove - ¿Por qué Git no usa SHA más moderno?



git remove tag (4)

Leí acerca de que Git usa el resumen SHA-1 como ID para una revisión. ¿Por qué no usa una versión más moderna de SHA?


¿Por qué no usa una versión más moderna de SHA?

Diciembre de 2017: lo hará. Y Git 2.16 (Q1 2018) es el primer lanzamiento para ilustrar e implementar esa intención.

Nota: vea 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 lo largo de varias rutas de código.

Ver commit c250e02 (28 de noviembre de 2017) por Ramsay Jones (``) .
Ver commit eb0ccfd , commit 78a6766 , commit f50e766 , commit abade65 (12 de noviembre de 2017) por brian m. bk2204 ( bk2204 ) .
(Fusionada por Junio ​​C Hamano - gitster - en commit 721cc43 , 13 dic 2017)

Agregar estructura que representa algoritmo hash

Como 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 enumeración fácil de algoritmos hash .
Implemente la función typedefs 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 que el otro, los dos valores se usan de manera extremadamente común en toda la base de código y proporcionan a ambos una mejor legibilidad.

No incluya una entrada en la estructura del algoritmo hash para la ID de objeto nulo.
Como este valor es todo ceros, se puede usar cualquier ID de objeto todo cero de tamaño adecuado, y no hay necesidad de almacenar uno dado 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.
Como no podemos saber qué ha proporcionado el usuario, agregue una constante que represente el algoritmo desconocido para permitirnos indicar que debemos buscar el valor correcto.

Integra el soporte del algoritmo hash con la configuración de 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 read_repository_format SHA-1, así que codifique este valor en read_repository_format .
En el futuro, enumeraremos este valor desde la configuración.

Agregue una constante, the_hash_algo , que apunta al puntero de estructura hash_algo en el repositorio global.
Tenga en cuenta que este es el hash que se utiliza para serializar datos en el disco, no el hash que se utiliza para mostrar elementos al usuario.
El plan de transición anticipa que estos pueden ser diferentes.
Podemos agregar un elemento adicional en el futuro (por ejemplo, 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.

Ver commit 0ed8d8d (04 de agosto de 2018) por Jonathan Nieder ( artagnon ) .
Ver commit 13f5e09 (25 de julio de 2018) por Ævar Arnfjörð Bjarmason ( avar ) .
(Fusionada por Junio ​​C Hamano - gitster - en commit 34f2297 , 20 ago 2018)

doc hash-function-transition : elija SHA-256 como NewHash

Desde 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, es ampliamente utilizado 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 más rápidas, incluso sin aceleración.

  • Si estamos haciendo firmas con OpenPGP (o incluso, supongo, CMS), vamos a utilizar SHA-2, por lo que no tiene sentido que nuestra seguridad dependa de dos algoritmos separados cuando uno de ellos solo podría romper la seguridad cuando solo pudiéramos depender de uno.

Entonces SHA-256 lo es .
Actualice el documento de diseño de transición de función hash para decirlo.

Después de este parche, no quedan instancias de la cadena " NewHash ", excepto por un uso no relacionado de 2008 como nombre de variable en t/t9700/test.pl

Puede ver esta transición a SHA 256 en progreso con Git 2.20 (Q4 2018):

Ver commit 0d7c419 , commit dda6346 , commit eccb5a5 , commit 93eb00f , commit d8a3a69 , commit fbd0e37 , commit f690b6b , commit 49d1660 , commit 268babd , commit fa13080 , commit 7b5e614 , commit 58ce21b , commit 2f0c9e9 , br15 , 15 de octubre de 2018 . bk2204 ( bk2204 ) .
Ver commit 6afedba (15 de octubre de 2018) por SZEDER Gábor ( szeder ) .
(Fusionada por Junio ​​C Hamano - gitster - en commit d829d49 , 30 oct 2018)

reemplazar constantes codificadas

Reemplace varias constantes basadas en 40 con referencias a GIT_MAX_HEXSZ o the_hash_algo , según corresponda.
Convierta todos los usos de GIT_SHA1_HEXSZ para usar the_hash_algo para que sean apropiados para cualquier longitud de hash dada.
En lugar de usar una constante codificada para el tamaño de una ID de objeto hexadecimal, cambie para usar el puntero calculado de parse_oid_hex que apunta después de la ID del objeto analizado.

GIT_SHA1_HEXSZ se elimina / reemplaza con Git 2.22 (Q2 2019) y se confirma d4e568b .

Esa transición continúa con Git 2.21 (Q1 2019), que agrega el hash sha-256 y lo conecta a través del código para permitir construir Git con el "NewHash".

Consulte commit 4b4e291 , commit 27dc04c , commit 13eeedb , commit c166599 , commit 37649b7 , commit a2ce0a7 , commit 50c817e , commit 9a3a0ff , commit 0dab712 , commit 47edb64 (14 de noviembre de 2018) y commit 2f90b9d , commit 1ccf07c br (22 de octubre de 2018) . bk2204 ( bk2204 ) .
(Fusionada por Junio ​​C Hamano - gitster - en commit 33e4ae9 , 29 ene 2019)

Agregue una implementación base de soporte SHA-256 (febrero de 2019)

SHA-1 es débil y necesitamos hacer la transición a una nueva función hash.
Desde hace algún tiempo, nos hemos referido a esta nueva función como NewHash .
Recientemente, decidimos elegir SHA-256 como NewHash .
Las razones detrás de la elección de SHA-256 se describen en este hilo y en el historial de confirmación del 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.
Optimízalo y reestructuralo para cumplir con nuestros estándares de codificación.
Obtenga 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 implementarán implementaciones más eficaces 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 a usar 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 OpenSSL

Ya tenemos disponibles rutinas OpenSSL 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 usando libgcrypt

En general, se obtiene un mejor rendimiento de las rutinas criptográficas escritas en ensamblado 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 razones de licencia.

La mayoría de los sistemas con GnuPG también tendrán libgcrypt , ya que es una dependencia de GnuPG.
libgcrypt también es más rápido que la implementación SHA1DC para mensajes de algunos KiB y más grandes.

A modo de comparación, en un Core i7-6600U, esta implementación procesa 16 fragmentos de KiB a 355 MiB / s, mientras que SHA1DC procesa fragmentos equivalentes a 337 MiB / s.

Además, libgcrypt tiene licencia bajo LGPL 2.1, que es compatible con la GPL. Agregue una implementación de SHA-256 que use libgcrypt.

El esfuerzo de actualización continúa con Git 2.24 (Q4 2019)

Véanse 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 95435f , commit , 984357 , cometer 703d2d4 , commit 9d958cc , commit 7962e04 , commit fee4930 (18 ago 2019) por brian m. bk2204 ( bk2204 ) .
(Fusionada por Junio ​​C Hamano - gitster - en commit 676278f , 11 oct 2019)

En lugar de usar GIT_SHA1_HEXSZ y constantes codificadas, cambie a usar the_hash_algo .


Ahora hay un plan de transición a un hash más fuerte, por lo que parece que en el futuro usará un hash más moderno que SHA-1. Del plan de transición actual :

Algunos hashes en consideración son SHA-256, SHA-512/256, SHA-256x16, K12 y BLAKE2bp-256


Esta es una discusión sobre la urgencia de migrar fuera de 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 lejos de sha1.

Se ha trabajado durante años para adaptar las estructuras de datos y protocolos de Mercurial para los sucesores de SHA1. El espacio de almacenamiento se asignó para hashes más grandes en nuestra estructura de registro de registros 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 en 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 se aleja de sha1 antes que Mercurial, siempre puede agregar otro nivel de seguridad manteniendo un espejo Mercurial local con hg-git .


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 por qué Git continúa usando SHA-1, pero estas pueden ser algunas de las razones:

  1. Git fue la creación de Linus Torvald, y Linus aparentemente no quiere sustituir SHA-1 con otro algoritmo de hash en este momento.
  2. Él hace afirmaciones plausibles de que los ataques exitosos basados ​​en colisiones SHA-1 contra Git son mucho más difíciles que lograr las colisiones en sí mismos, y teniendo en cuenta que SHA-1 es más débil de lo que debería, no está completamente roto, eso lo hace sustancialmente lejos de ser ataque viable al menos hoy. Además, señala que un ataque "exitoso" lograría muy poco si el objeto en colisión llega más tarde que el existente, ya que se supondría que el último es el mismo que el válido e ignorado (aunque otros han señalado que lo contrario podría ocurrir).
  3. El cambio de software lleva mucho tiempo y es propenso a errores, especialmente cuando hay infraestructura y datos existentes basados ​​en los protocolos existentes que deberán migrarse. Incluso aquellos que producen productos de software y hardware donde la seguridad criptográfica es el único punto del sistema todavía están en proceso de migrar lejos de SHA-1 y otros algoritmos débiles en algunos lugares. Imagínense todos esos buffers de unsigned char[20] codificar por todas partes ;-), es mucho más fácil programar la agilidad criptográfica al principio, en lugar de adaptarla más tarde.
  4. El rendimiento de SHA-1 es mejor que los diversos hash de SHA-2 (probablemente no tanto como para ser un factor decisivo ahora, pero tal vez fue un punto de conflicto hace 10 años), y el tamaño de almacenamiento de SHA-2 es mayor .

Algunos enlaces:

Mi opinión personal sería que, si bien los ataques prácticos son probablemente un tiempo libre, e incluso cuando ocurren, las personas probablemente mitigarán inicialmente contra ellos con otros medios que no sean cambiar el algoritmo hash en sí, que si te preocupa la seguridad, deberías equivocarte por el lado de la precaución con sus elecciones de algoritmos, y revisando continuamente 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 usar SHA-1 no pretende ser seguridad criptográfica.