Quantos elementos aleatórios antes do MD5 produzem colisões?

Eu tenho uma biblioteca de imagens no Amazon S3. Para cada imagem, eu md5 o URL de origem no meu servidor, além de um registro de data e hora para obter um nome de arquivo exclusivo. Como o S3 não pode ter subdiretórios, preciso armazenar todas essas imagens em uma única pasta simples.

Preciso me preocupar com colisões no valor do hash MD5 que é produzido?

Bônus: Quantos arquivos eu poderia ter antes de começar a ver colisões no valor de hash que o MD5 produz?

131
adicionado o autor kenorb, fonte
A resposta literal é que o arquivo segundo pode ter o mesmo MD5 que o primeiro. No entanto, as chances são extremamente pequenas.
adicionado o autor Rick James, fonte

8 Respostas

Probabilidade de apenas dois hashes acidentalmente colidirem é 1/2 128 que é 1 em 340 undecillion 282 decillion 366 nonillion 920 octillion 938 septillion 463 sextillion 463 quintillion 374 quadrilhões 607 trilhões 431 bilhões 768 milhões 211 mil 456.

No entanto, se você mantiver todos os hashes, a probabilidade é um pouco maior graças ao paradoxo do aniversário . Para ter 50% de chance de qualquer hash colidir com qualquer outro hash você precisa de hashes 2 64 . Isso significa que para obter uma colisão, em média, você precisará do hash 6 bilhões arquivos por segundo por 100 anos .

238
adicionado
Então você está dizendo que há uma chance!
adicionado o autor vargonian, fonte
"probabilidade de colisão é 1/2 ^ 64" - o que? A probabilidade de colisão depende do número de itens já hashed, não é um número fixo. Na verdade, é igual a exatamente 1 - sPn/s ^ n , onde s é o tamanho do espaço de pesquisa ( 2 ^ 128 em Neste caso), e n é o número de itens hash. O que você provavelmente está pensando é 2 ^ 64 , que é o número aproximado de itens que você precisa para o hash MD5 para ter 50% de chance de colisão.
adicionado o autor BlueRaja - Danny Pflughoeft, fonte
JørgenFogh: E todas as leis da física também não estão "corretas". Esse nível de pedantismo é desnecessário porque não altera a resposta de maneira significativa.
adicionado o autor Kornel, fonte
@yaauie Não, isso é ridiculamente impossível. Estou falando de gerar 2 ^ 64 hashes de 2 ^ 128 possíveis. Isso é um quadrilionésimo de um por cento de todos os hashes possíveis gerados.
adicionado o autor Kornel, fonte
@ BlueRaja-DannyPflughoeft que é o que eu tinha em mente, de fato. Obrigado pela correção.
adicionado o autor Kornel, fonte
@ConcernedOfTunbridgeWells: Eu fiz a correção para o paradoxo do aniversário, e é por isso que a resposta está em bilhões, não em quintilhões. Não foi possível verificar a probabilidade com seu script PV = 2 ** 128; SS = 2 ** 64 : OverflowError: long int grande demais para converter int
adicionado o autor Kornel, fonte
Não é estritamente verdade. A probabilidade de uma colisão é muito maior do que isso, pois uma nova URL poderia colidir com qualquer item existente na tabela. Veja Esta postagem (aviso legal, eu escrevi isso) para uma corrida na matemática, e um pequeno script python que pode ser adaptado para calcular a probabilidade de um determinado número de URLs.
adicionado o autor ConcernedOfTunbridgeWells, fonte
Infelizmente, você ainda não está correto. Você está assumindo que a função hash é verdadeiramente aleatória. Não é. Isso significa que a probabilidade de colisão é maior.
adicionado o autor Jørgen Fogh, fonte
+1 para adicionar o cálculo. Isso é um pouco mais preciso: http://www.google.com/search?q=2^64%2F100* (segundos + por + ano)
adicionado o autor Mathias Bynens, fonte
(Isso significa que, para obter uma colisão, você precisará, em média, obter 6 bilhões de arquivos por segundo durante 100 anos.); incorreta. Isso significa que, pelo tempo que você está processando 6 bilhões de arquivos por segundo durante 100 anos, 50% dos hashes que você está gerando colidiriam com hashes gerados anteriormente.
adicionado o autor yaauie, fonte
+1 porque eu sempre quis saber como contar mais de 999 trilhões de lol (e, oh sim, sua resposta foi informativa)
adicionado o autor Kmeixner, fonte
Intuitivamente, se ignorarmos o paradoxo de aniversário e apenas olharmos para uma solução aproximada: Adicione hashes 2 ^ 64 em uma lista. Agora adicione mais um hash a essa lista. Esse mais um hash tem 1/2 ^ 128 vezes 2 ^ 64 chance de uma colisão, ou seja, que mais um hash tem um 1/2 ^ 64 chance de uma colisão. Agora adicione outros hashes 2 ^ 64 à lista e você deverá obter uma colisão. Faça o mesmo cálculo para 2 ^ 63 (e anote 2 ^ 63 + 2 ^ 63 = 2 ^ 64 ).
adicionado o autor robocat, fonte

S3 pode ter subdiretórios. Basta colocar um "/" no nome da chave, e você pode acessar os arquivos como se estivessem em diretórios separados. Eu uso isso para armazenar arquivos de usuário em pastas separadas com base em seu ID de usuário no S3.

Por exemplo: "mybucket/users/1234/somefile.jpg". Não é exatamente o mesmo que um diretório em um sistema de arquivos, mas a API do S3 tem alguns recursos que permitem que funcione quase da mesma forma. Eu posso pedir para listar todos os arquivos que começam com "users/1234 /" e ele me mostrará todos os arquivos naquele "diretório".

22
adicionado
Isso deve ser um conteúdo, eu acho, pois na verdade não responde à pergunta sobre a probabilidade de uma colisão
adicionado o autor Ian Clark, fonte

Então espere, é isso:

md5(filename) + timestamp

ou:

md5(filename + timestamp)

Se o primeiro, você é mais do caminho para um GUID, e eu não me preocuparia com isso. Se este último, em seguida, consulte o post de Karg sobre como você vai colidir com colisões eventualmente.

16
adicionado
@BradThomas: isso não acontece. O risco de colisão MD5 é o mesmo, seja no nome do arquivo ou na combinação de nome de arquivo e registro de data e hora. Mas no primeiro cenário, você precisaria ter uma colisão MD5 e uma colisão de timestamp.
adicionado o autor Vincent Hubert, fonte
Isso ainda deixa uma chance de 2 ^ (128 ^ 60) de uma colisão com dois usuários por minuto. Literalmente inutilizável.
adicionado o autor Berry M., fonte
Por favor, explique como incluir o timestamp aumenta a chance de colisão
adicionado o autor Brad Thomas, fonte
@BradThomas Para ser mais claro: md5 (filename) + timestamp reduz massivamente o risco de colisão porque você precisaria ter uma colisão md5 exatamente para o mesmo timestamp para ter uma colisão geral. md5 (filename + timestamp) é o mesmo que md5 (filename) , assumindo que o nome do arquivo é aleatório para começar (porque adicionar mais aleatoriedade a algo aleatório apenas muda o md5 individual resultado e o problema de aniversário ainda existe em todos os hashes md5).
adicionado o autor robocat, fonte

Uma regra básica para colisões é a raiz quadrada do intervalo de valores. Seu sinal MD5 provavelmente tem 128 bits de comprimento, então você provavelmente verá colisões acima e além de 2 ^ 64 imagens.

10
adicionado
en.wikipedia.org/wiki/Birthday_Problem Mais informações sobre o problema.
adicionado o autor Georg Schölly, fonte
Você provavelmente quer dizer 128 bits, não 2 ^ 128. :-)
adicionado o autor JesperE, fonte

Embora as colisões aleatórias com MD5 sejam extremamente raras, se os usuários puderem fornecer arquivos (que serão armazenados na íntegra), eles poderão criar colisões para que ocorram. Ou seja, eles podem criar deliberadamente dois arquivos com o mesmo MD5sum, mas com dados diferentes. Certifique-se de que sua aplicação possa lidar com este caso de uma maneira sensata, ou talvez use um hash mais forte como o SHA-256.

7
adicionado
usar um sal cuidaria do problema de engenharia do usuário, não?
adicionado o autor StackOverflowed, fonte
Depende de como o sal é aplicado. Ele precisaria ser um prefixo dos dados fornecidos pelo usuário ou, melhor ainda, a chave para um HMAC. Ainda é uma boa ideia praticar a defesa em profundidade.
adicionado o autor bdonlan, fonte
Observe que, embora o SHA256 tenha 256 bits, você pode compensar o risco de colisões com o tamanho da chave que está armazenando, truncando o SHA256 para menos bits. use o SHA256, mas truncá-lo para 128 bits (o que é mais seguro do que usar o MD5, embora eles tenham o mesmo número de bits).
adicionado o autor robocat, fonte

Embora tenha havido problemas bem divulgados com o MD5 devido a colisões, as colisões não intencionais entre dados aleatórios são excessivamente raro . Por outro lado, se você estiver fazendo hash no nome do arquivo, isso não é um dado aleatório, e eu esperaria colisões rapidamente.

3
adicionado
O único problema que tenho com o exemplo do taylors é que, se alguém conseguir uma cópia do seu banco de dados, provavelmente descobriria os números do cartão de crédito usando uma tabela do arco-íris ...
adicionado o autor Sam Saffron, fonte
Enquanto eu não escolheria usar MD5 para cartões de crédito, uma tabela Rainbow de todos os números de cartão de crédito válidos entre 10.000.000 (8 dígitos sendo o menor cartão de crédito que já vi) e 9.999.999.999.999.999 (maior número de 16 dígitos) ainda é um grande tabela para gerar. Existem provavelmente maneiras mais fáceis de roubar esses números.
adicionado o autor acrosman, fonte

Colisão MD5 é extremamente improvável. Se você tem 9 trilhões MD5s, há apenas uma chance em 9 trilhões de haver uma colisão.

0
adicionado
Muitas das outras respostas falam sobre a probabilidade de uma colisão ao adicionar um item a mais. Eu acho que minha resposta é mais útil porque fala sobre o provável de toda a tabela com um dup.
adicionado o autor Rick James, fonte

Não importa realmente como é provável; é possível. Pode acontecer nas duas primeiras coisas que você hash (muito improvável, mas possível), então você precisará suportar colisões desde o início.

0
adicionado
É claro que pode haver muitas outras coisas ruins que podem acontecer com uma probabilidade de 1/2 ^ 128. Você pode não querer destacar este para se preocupar.
adicionado o autor Will Dean, fonte
Você não pode estar falando sério. Você precisará haxar 6 bilhões de arquivos por segundo, a cada segundo durante 100 anos, para ter boas chances de colisão. Mesmo se você for muito infeliz, provavelmente levaria mais do que a capacidade total do S3 usada por mais tempo do que a vida humana.
adicionado o autor Kornel, fonte
A pior coisa que pode acontecer aqui é que você pode tirar uma foto. Para um número relativamente pequeno, eu não me preocuparia. Agora, se o seu software está controlando um piloto automático pousando uma aeronave, isso é outra história.
adicionado o autor Jim C, fonte
É bilhões de vezes mais provável que seu banco de dados e seus backups falhem. Colisões não valem a pena se preocupar.
adicionado o autor Artelius, fonte
Use o tempo de prevenção de colisão construindo um bunker para colocar seu servidor! Esses meteoros incômodos podem te atingir (muito improvável, mas possível), então você precisará apoiar o abrigo de meteoros desde o começo.
adicionado o autor polvoazul, fonte
Levaria 100 anos para obter uma chance de 50% de colisão em arquivos de 6G/s. Você tem uma boa chance de colisão décadas antes.
adicionado o autor user327961, fonte