Eu li sobre que o Git usa o resumo SHA-1 como um ID para uma revisão. Por que não usa uma versão mais moderna do SHA?
Eu li sobre que o Git usa o resumo SHA-1 como um ID para uma revisão. Por que não usa uma versão mais moderna do SHA?
Respostas:
Por que não usa uma versão mais moderna do SHA?
Dezembro de 2017: Vai. E o Git 2.16 (primeiro trimestre de 2018) é o primeiro lançamento para ilustrar e implementar essa intenção.
Nota: veja Git 2.19 abaixo: será SHA-256 .
O Git 2.16 irá propor uma infraestrutura para definir qual função hash é usada no Git e iniciará um esforço para sondar isso em vários codepaths.
Consulte commit c250e02 (28 de novembro de 2017) por Ramsay Jones (``) .
Consulte commit eb0ccfd , commit 78a6766 , commit f50e766 , commit abade65 (12 nov 2017) por brian m. Carlson ( bk2204
) .
(Fundido por Junio C Hamano - gitster
- no commit 721cc43 , 13 de dezembro de 2017)
Adicionar estrutura que representa o algoritmo hash
Como no futuro queremos oferecer suporte a um algoritmo hash adicional, adicione uma estrutura que represente um algoritmo hash e todos os dados que devem acompanhá-lo .
Adicione uma constante para permitir a enumeração fácil de algoritmos de hash .
Implemente a funçãotypedefs
para criar uma API abstrata que pode ser usada por qualquer algoritmo hash e wrappers para as funções SHA1 existentes que estão em conformidade com esta API.Exponha um valor para o tamanho hexadecimal, bem como para o tamanho binário .
Embora um seja sempre o dobro do outro, os dois valores são usados de forma extremamente comum em toda a base de código e fornecer ambos leva a uma legibilidade aprimorada.Não inclua uma entrada na estrutura do algoritmo hash para o ID de objeto nulo.
Como esse valor é composto apenas por zeros, qualquer ID de objeto totalmente zero de tamanho adequado pode ser usado e não há necessidade de armazenar um determinado por hash.O plano de transição da função hash atual prevê um momento em que aceitaremos a entrada do usuário que pode estar em SHA-1 ou no formato NewHash.
Como não podemos saber qual foi o usuário fornecido, adicione uma constante representando o algoritmo desconhecido para nos permitir indicar que devemos procurar o valor correto.
Integre o suporte ao algoritmo hash com a configuração do repo
Em versões futuras do Git, planejamos oferecer suporte a um algoritmo hash adicional.
Integre a enumeração de algoritmos de hash com a configuração do repositório e armazene um ponteiro para os dados enumerados no repositório de struct .
Claro, atualmente só oferecemos suporte a SHA-1, portanto, codifique esse valor emread_repository_format
.
No futuro, vamos enumerar esse valor da configuração.Adicione uma constante,,
the_hash_algo
que aponta para ohash_algo
ponteiro da estrutura no repositório global.
Observe que este é o hash que é usado para serializar dados no disco, não o hash que é usado para exibir itens para o usuário.
O plano de transição prevê que eles possam ser diferentes.
Podemos adicionar um elemento adicional no futuro (digamos,ui_hash_algo
) para fornecer para este caso.
Atualização de agosto de 2018, para Git 2.19 (terceiro trimestre de 2018), Git parece escolher SHA-256 como NewHash.
Veja o commit 0ed8d8d (04 de agosto de 2018) de Jonathan Nieder ( artagnon
) .
Veja o commit 13f5e09 (25 de julho de 2018) de Ævar Arnfjörð Bjarmason ( avar
) .
(Incorporado por Junio C Hamano - gitster
- no commit 34f2297 , 20 de agosto de 2018)
doc
hash-function-transition
: escolha SHA-256 como NewHashDo ponto de vista da segurança, parece que SHA-256, BLAKE2, SHA3-256, K12 e assim por diante têm propriedades de segurança semelhantes.
Todas são boas opções do ponto de vista da segurança.SHA-256 tem uma série de vantagens:
Já existe há algum tempo, é amplamente usado e é suportado por quase todas as bibliotecas de criptografia (OpenSSL, mbedTLS, CryptoNG, SecureTransport, etc).
Quando você compara com o SHA1DC, a maioria das implementações vetorizadas do SHA-256 são realmente mais rápidas, mesmo sem aceleração.
Se estivermos fazendo assinaturas com OpenPGP (ou mesmo, suponho, CMS), vamos usar SHA-2, então não faz sentido ter nossa segurança dependente de dois algoritmos separados quando um deles sozinho poderia quebrar a segurança quando podíamos apenas depender de um.
Então é SHA-256 .
Atualize o documento de design da transição da função hash para dizer isso.Após este patch, não há instâncias restantes da string "
NewHash
", exceto para um uso não relacionado de 2008 como um nome de variável emt/t9700/test.pl
.
Você pode ver esta transição para SHA 256 em andamento com Git 2.20 (quarto trimestre de 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 out 2018) por Brian M . Carlson ( bk2204
) .
Ver commit 6afedba (15 out 2018) de SZEDER Gábor ( szeder
) .
(Fundido porJunio C Hamano - gitster
- no commit d829d49 , 30 de outubro de 2018)
substitua constantes codificadas
Substitua várias constantes baseadas em 40 por referências a
GIT_MAX_HEXSZ
outhe_hash_algo
, conforme apropriado.
Converta todos os usos doGIT_SHA1_HEXSZ
para usar dethe_hash_algo
modo que sejam apropriados para qualquer comprimento de hash dado.
Em vez de usar uma constante codificada para o tamanho de um ID de objeto hexadecimal, mude para usar o ponteiro calculado a partirparse_oid_hex
desses pontos após o ID de objeto analisado.
GIT_SHA1_HEXSZ
é posteriormente removido / substituído pelo Git 2.22 (Q2 2019) e commit d4e568b .
Essa transição continua com o Git 2.21 (primeiro trimestre de 2019), que adiciona o hash sha-256 e o conecta por meio do código para permitir a construção do Git com o "NewHash".
Ver cometer 4b4e291 , cometer 27dc04c , cometer 13eeedb , cometer c166599 , cometer 37649b7 , cometer a2ce0a7 , cometer 50c817e , cometer 9a3a0ff , cometer 0dab712 , cometer 47edb64 (14 novembro de 2018), e cometer 2f90b9d , cometer 1ccf07c (22 de outubro de 2018) por Brian M . Carlson ( bk2204
) .
(Incorporado por Junio C Hamano - gitster
- no commit 33e4ae9 , 29 de janeiro de 2019)
Adicionar uma implementação básica de suporte SHA-256 (fevereiro de 2019)
SHA-1 é fraco e precisamos fazer a transição para uma nova função hash.
Por algum tempo, nos referimos a essa nova função comoNewHash
.
Recentemente, decidimos escolher SHA-256 comoNewHash
.
As razões por trás da escolha do SHA-256 são descritas neste tópico e no histórico de commits para o documento de transição da função hash.Adicione uma implementação básica baseada em SHA-256
libtomcrypt
, que é de domínio público.
Otimize-o e reestruture-o para atender aos nossos padrões de codificação.
Puxe as funções de atualização e final da implementação do bloco SHA-1, pois sabemos que elas funcionam corretamente com todos os compiladores. Esta implementação é mais lenta que SHA-1, mas mais implementações de desempenho serão introduzidas em commits futuros.Conecte o SHA-256 à lista de algoritmos de hash e adicione um teste de que o algoritmo funciona corretamente.
Observe que com este patch, ainda não é possível mudar para o uso de SHA-256 no Git.
Patches adicionais são necessários para preparar o código para lidar com um algoritmo hash maior e outras correções de teste são necessárias.
hash
: adicione uma implementação SHA-256 usando OpenSSLJá temos rotinas OpenSSL disponíveis para SHA-1, então adicione rotinas para SHA-256 também.
Em um Core i7-6600U, esta implementação SHA-256 se compara favoravelmente à implementação 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
: adicione uma implementação SHA-256 usandolibgcrypt
Geralmente, obtém-se melhor desempenho de rotinas criptográficas escritas em assembly do que C, e isso também é verdadeiro para SHA-256.
Além disso, a maioria das distribuições Linux não pode distribuir Git vinculado ao OpenSSL por motivos de licenciamento.A maioria dos sistemas com GnuPG também terá
libgcrypt
, uma vez que é uma dependência do GnuPG.
libgcrypt
também é mais rápido do que a implementação SHA1DC para mensagens de alguns KiB e maiores.Para comparação, em um Core i7-6600U, esta implementação processa pedaços de 16 KiB a 355 MiB / s, enquanto o SHA1DC processa pedaços equivalentes a 337 MiB / s.
Além disso, libgcrypt é licenciado sob a LGPL 2.1, que é compatível com a GPL. Adicione uma implementação de SHA-256 que usa libgcrypt.
O esforço de atualização continua com o Git 2.24 (quarto trimestre de 2019)
Veja commit aaa95df , commit be8e172 , commit 3f34d70 , commit fc06be3 , commit 69fa337 , commit 3a4d7aa , commit e0cb7cd , commit 8d4d86b , cometer f6ca67d , cometer dd336a5 , cometer 894c0f6 , cometer 4439c7a , cometer 95518fa , cometer e84f357 , cometer fe9fec4 , cometer 976ff7e , cometer 703d2d4 , cometer 9d958cc , cometer 7962e04 , cometer taxa 4930(18 de agosto de 2019) por brian m. Carlson ( bk2204
) .
(Incorporado por Junio C Hamano - gitster
- no commit 676278f , 11 de outubro de 2019)
Em vez de usar
GIT_SHA1_HEXSZ
e constantes codificadas, mude para usarthe_hash_algo
.
Com o Git 2.26 (Q1 2020), os scripts de teste estão prontos para o dia em que os nomes dos objetos usarão SHA-256.
Ver commit 277eb5a , commit 44b6c05 , commit 7a868c5 , commit 1b8f39f , commit a8c17e3 , commit 8320722 , commit 74ad99b , commit ba1be1a , commit cba472d , commit 82d5aeb , commit 3c5e65c , cometer 235d3cd , cometer 1d86c8f , cometer 525a7f1 , cometer 7a1bcb2 , cometer cb78f4f , cometer 717c939 , commit 08a9dd8 , commit 215b60b , commit 194264c(21 de dezembro de 2019) por brian m. Carlson ( bk2204
) .
(Fundido por Junio C Hamano - gitster
- no commit f52ab33 , 05 de fevereiro de 2020)
Exemplo:
t4204
: torna o tamanho do hash independenteAssinado por: brian m. Carlson
Use em
$OID_REGEX
vez de uma expressão regular codificada.
Então, em vez de usar:
grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output
Os testes estão usando
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
E OID_REGEX
vem de commit bdee9cd (13 de maio de 2018) por brian m. Carlson ( bk2204
) .
(Incorporado por Junio C Hamano - gitster
- no commit 9472b13 , 30 de maio de 2018, Git v2.18.0-rc0)
t/test-lib
: introduzirOID_REGEX
Assinado por: brian m. Carlson
Atualmente temos uma variável,
$_x40,
que contém uma regex que corresponde a uma constante hexadecimal completa de 40 caracteres.No entanto, com
NewHash
, teremos IDs de objeto com mais de 40 caracteres.Nesse caso,
$_x40
será um nome confuso.Crie um
$OID_REGEX
variável que sempre refletirá uma regex correspondente ao ID de objeto apropriado, independentemente do comprimento do hash atual.
E, ainda para testes:
Ver commit f303765 , commit edf0424 , commit 5db24dc , commit d341e08 , commit 88ed241 , commit 48c10cc , commit f7ae8e6 , commit e70649b , commit a30f93b , commit a79eec2 , commit 796d138 , commit 417e45e , brian m. Carlson ( cometer dfa5f53 , cometer f743e8f , cometer 72f936b , cometer 5df0f11 , cometer 07877f3 , commit 6025e89 , commit 7b1a182 , commit 94db7e3 ,commit db12505 (07 Fev 2020) porbk2204
) .
(Fundido por Junio C Hamano - gitster
- no commit 5af345a , 17 de fevereiro de 2020)
t5703
: faça o teste funcionar com SHA-256Assinado por: brian m. Carlson
Este teste usou um ID de objeto com 40 caracteres hexadecimais de comprimento, fazendo com que o teste não apenas não passasse, mas travasse, quando executado com SHA-256 como hash.
Altere este valor para um ID de objeto fictício fixo usando
test_oid_init
etest_oid
.Além disso, certifique-se de extrair um ID de objeto do comprimento apropriado usando corte com campos em vez de um comprimento fixo.
Alguns codepaths receberam uma instância de repositório como parâmetro para trabalhar no repositório, mas passaram the_repository
instância para seus callees, que foram limpos (um pouco) com Git 2.26 (Q1 2020).
Veja commit b98d188 , commit 2dcde20 , commit 7ad5c44 , commit c8123e7 , commit 5ec9b8a , commit a651946 , commit eb999b3 (30 Jan 2020) por Matheus Tavares ( matheustavares
) .
(Fundido por Junio C Hamano - gitster
- no commit 78e67cd , 14 de fevereiro de 2020)
sha1-file
: permitecheck_object_signature()
lidar com qualquer repoAssinado por: Matheus Tavares
Alguns chamadores de
check_object_signature()
podem trabalhar em repositórios arbitrários, mas o repo não é passado para esta função. Em vez disso,the_repository
é sempre usado internamente.
Para corrigir possíveis inconsistências, permita que a função receba um repositório de struct e faça com que esses chamadores repassem o repo que está sendo tratado.
Baseado em:
sha1-file
: passegit_hash_algo
parahash_object_file()
Assinado por: Matheus Tavares
Permitir
hash_object_file()
trabalhar em repositórios arbitrários, introduzindo umgit_hash_algo
parâmetro. Altere os chamadores que têm um ponteiro de repositório de struct em seu escopo para passargit_hash_algo
adiante do referido repo.
Para todos os outros chamadores, repassethe_hash_algo
, que já estava sendo usado internamente emhash_object_file()
.
Esta funcionalidade será usada no seguinte patch paracheck_object_signature()
possibilitar o trabalho em repositórios arbitrários (que, por sua vez, serão usados para corrigir uma inconsistência emobject.c
: parse_object ()).
git rev-parse
agora pode imprimir o hash que será usado: stackoverflow.com/a/58862319/6309 . E a árvore vazia tem um novo id
ATUALIZAÇÃO : a pergunta acima e esta resposta são de 2015. Desde então, o Google anunciou a primeira colisão SHA-1: https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
Obviamente, só posso especular de fora sobre o motivo pelo qual o Git continua a usar SHA-1, mas esses podem estar entre os motivos:
unsigned char[20]
buffers codificados por todo o lugar ;-), é muito mais fácil programar para agilidade criptográfica no início, em vez de adaptá-la mais tarde.Alguns links:
Minha opinião pessoal seria que, embora os ataques práticos provavelmente demorem algum tempo, e mesmo quando eles ocorrerem, as pessoas provavelmente irão inicialmente mitigá-los com outros meios além de alterar o próprio algoritmo de hash, que se você se preocupa com a segurança, estará errando do lado da cautela com suas escolhas de algoritmos e continuamente revisando para cima seus pontos fortes de segurança, porque as capacidades dos invasores também estão indo apenas em uma direção, então não seria sábio tomar o Git como um modelo, especialmente como seu propósito em o uso de SHA-1 não pretende ser uma segurança criptográfica.
Esta é uma discussão sobre a urgência de migrar do SHA1 para o Mercurial, mas se aplica ao Git também: https://www.mercurial-scm.org/wiki/mpm/SHA1
Resumindo: se você não for extremamente diligente hoje, terá vulnerabilidades muito piores do que sha1. Mas, apesar disso, o Mercurial começou há mais de 10 anos para se preparar para migrar para longe do sha1.
o trabalho está em andamento há anos para adaptar as estruturas de dados e protocolos do Mercurial para os sucessores do SHA1. O espaço de armazenamento foi alocado para hashes maiores em nossa estrutura de revlog há mais de 10 anos no Mercurial 0.9 com a introdução do RevlogNG. O formato bundle2 introduzido mais recentemente suporta a troca de diferentes tipos de hash pela rede. As únicas peças restantes são a escolha de uma função de substituição e a escolha de uma estratégia de compatibilidade com versões anteriores.
Se o git não migrar de sha1 antes do Mercurial, você sempre poderá adicionar outro nível de segurança mantendo um espelho local do Mercurial com hg-git .
Agora há um plano de transição para um hash mais forte, então parece que no futuro ele usará um hash mais moderno do que SHA-1. Do plano de transição atual :
Alguns hashes em consideração são SHA-256, SHA-512/256, SHA-256x16, K12 e BLAKE2bp-256