Provavelmente isso nunca aconteceu no mundo real ainda, e pode nunca acontecer, mas vamos considerar o seguinte: digamos que você tenha um repositório git, faça um commit e fique muito azarado: um dos blobs acaba tendo o mesmo SHA-1 como outro que já está no seu repositório. A questão é: como o Git lidaria com isso? Simplesmente falhar? Encontrar uma maneira de vincular os dois blobs e verificar qual deles é necessário de acordo com o contexto?
Mais um quebra-cabeças do que um problema real, mas achei a questão interessante.
git
hash-collision
Gnurou
fonte
fonte
Respostas:
Fiz um experimento para descobrir exatamente como o Git se comportaria nesse caso. Esta é a versão 2.7.9 ~ rc0 + next.20151210 (versão Debian). Basicamente, reduzi o tamanho do hash de 160 para 4 bits aplicando o seguinte diff e reconstruindo o git:
Depois fiz alguns commits e notei o seguinte.
Para o número 2, você normalmente receberá um erro como esse ao executar o "git push":
ou:
se você excluir o arquivo e executar "git checkout file.txt".
Para os nºs 4 e 6, você normalmente receberá um erro como este:
ao executar "git commit". Nesse caso, você pode digitar apenas "git commit" novamente, pois isso criará um novo hash (devido ao carimbo de data / hora alterado)
Para os nºs 5 e 9, você normalmente receberá um erro como este:
ao executar "git commit"
Se alguém tentar clonar seu repositório corrompido, normalmente verá algo como:
O que "me preocupa" é que em dois casos (2,3) o repositório fica corrompido sem nenhum aviso e em 3 casos (1,7,8) tudo parece ok, mas o conteúdo do repositório é diferente do que você espera. ser estar. As pessoas que clonam ou puxam terão um conteúdo diferente do que você possui. Os casos 4,5,6 e 9 estão corretos, pois parará com um erro. Suponho que seria melhor se falhasse com um erro, pelo menos em todos os casos.
fonte
Resposta original (2012) (ver
shattered.io
colisão SHA1 2017 abaixo)Essa antiga resposta (2006) de Linus ainda pode ser relevante:
A questão do uso do SHA-256 é mencionada regularmente, mas não é adotada por enquanto (2012).
Nota: a partir de 2018 e do Git 2.19 , o código está sendo refatorado para usar o SHA-256.
Nota (Humor): você pode forçar uma confirmação para um prefixo SHA1 específico , com o projeto gitbrute de Brad Fitzpatrick (
bradfitz
) .Exemplo: https://github.com/bradfitz/deadbeef
Daniel Dinnyes aponta nos comentários para 7.1 Git Tools - Revision Selection , que inclui:
Até os mais recentes (fevereiro de 2017)
shattered.io
demonstraram a possibilidade de forjar uma colisão com SHA1:(veja muito mais em minha resposta separada , incluindo a postagem do Google+ de Linus Torvalds)
Consulte " Vida útil das funções de hash criptográfico " da Valerie Anita Aurora para obter mais informações.
Nessa página, ela observa:
Veja mais em minha resposta separada abaixo .
fonte
/* This line added to avoid collision */
: D você pode ganhar na loteria duas vezes: P/* This line added to avoid collision of the avoid collision line */
De acordo com o Pro Git :
Portanto, não falharia, mas também não salvaria seu novo objeto.
Não sei como isso ficaria na linha de comando, mas isso certamente seria confuso.
Um pouco mais adiante, essa mesma referência tenta ilustrar a probabilidade de tal colisão:
fonte
Para adicionar à minha resposta anterior de 2012 , existe agora (fevereiro de 2017, cinco anos depois), um exemplo de colisão SHA-1 com shattered.io , onde você pode criar dois arquivos PDF em colisão: que é obter um SHA- 1 assinatura digital no primeiro arquivo PDF que também pode ser abusada como uma assinatura válida no segundo arquivo PDF.
Veja também " À porta da morte há anos, a função SHA1 amplamente utilizada agora está morta ", e esta ilustração .
Atualização 26 de fevereiro: Linus confirmou os seguintes pontos em uma postagem do Google+ :
Sobre essa transição, consulte o primeiro trimestre de 2018 Git 2.16 adicionando uma estrutura representando o algoritmo de hash. A implementação dessa transição foi iniciada.
Iniciando o Git 2.19 (terceiro trimestre de 2018) , o Git escolheu SHA-256 como NewHash e está no processo de integrá-lo ao código (o que significa que o SHA1 ainda é o padrão (Q2 2019, Git 2.21), mas o SHA2 será o sucessor)
Resposta original (25 de fevereiro) Mas:
Ele tem algum problema para
git-svn
que . Ou melhor, com o próprio svn , como pode visto aqui .git fsck
, conforme mencionado hoje por Linus Torvalds .git fsck
alertaria sobre uma mensagem de confirmação com dados opacos ocultos após aNUL
(emboraNUL
nem sempre esteja presente em um arquivo fraudulento ).Nem todo mundo liga
transfer.fsck
, mas o GitHub faz: qualquer push será abortado no caso de um objeto malformado ou um link quebrado. Embora ... haja um motivo para isso não ser ativado por padrão .O problema real na criação de dois repositórios Git com o mesmo cabeçalho de confirmação de hash e conteúdos diferentes. E mesmo assim, o ataque continua complicado .
Joey Hess experimenta esses pdf em um repositório Git e descobriu :
Portanto, o principal vetor de ataque (forjando um commit) seria :
Além disso, você já pode e detecta ataques de colisão criptoanalítica contra o SHA-1 presente em cada arquivo com
cr-marcstevens/sha1collisiondetection
Adicionar uma verificação semelhante no próprio Git teria algum custo de computação .
Sobre a alteração de hash, o Linux comenta :
Ainda assim, um plano de transição (do SHA1 para outra função de hash) ainda seria complexo , mas estudado ativamente.
Uma
convert-to-object_id
campanha está em andamento :Atualização 20 de março: O GitHub detalha um possível ataque e sua proteção :
Proteção:
Ver "
sha1collisiondetection
" por Marc StevensNovamente, com o primeiro trimestre de 2018 Git 2.16 adicionando uma estrutura representando o algoritmo de hash, a implementação de uma transição para um novo hash foi iniciada.
Como mencionado acima, o novo Hash suportado será o SHA-256 .
fonte
git-svn
", refere-se a ele, embora indiretamente))Eu acho que os criptografadores comemorariam.
Citação do artigo da Wikipedia sobre SHA-1 :
fonte
y
tal queh(x) ==
h (y) `, que é uma ameaça séria para dados arbitrários como certificados SSL, mas isso não afeta o Git, que seria vulnerável a um segundo ataque de pré-imagem, o que significa que tendo mensagemx
você pode modificá-lo à mensagemx'
queh(x) == h(x')
. Portanto, este ataque não enfraquece o Git. Além disso, o Git não escolheu o SHA-1 por razões de segurança.Existem vários modelos de ataque diferentes para hashes como o SHA-1, mas o geralmente discutido é a pesquisa de colisões, incluindo a ferramenta HashClash de Marc Stevens .
Como as pessoas apontaram, você pode forçar uma colisão de hash com o git, mas isso não substituirá os objetos existentes em outro repositório. Eu imagino mesmo
git push -f --no-thin
que nem substituirá os objetos existentes, mas não tenho 100% de certeza.Dito isto, se você invadir um repositório remoto, poderá tornar seu objeto falso o mais antigo existente , possivelmente incorporação de código invadiu um projeto open source no GitHub ou similar. Se você fosse cuidadoso, talvez pudesse introduzir uma versão invadida que os novos usuários baixaram.
Suspeito, no entanto, que muitas coisas que os desenvolvedores do projeto possam fazer possam expor ou destruir acidentalmente seu hack de vários milhões de dólares. Em particular, é muito dinheiro pelo ralo, se algum desenvolvedor, que você não invadiu, executar o mencionado acima
git push --no-thin
depois de modificar os arquivos afetados, às vezes até sem a--no-thin
dependência.fonte