Pular para o conteúdo
Todos os conceitos

Integridade de arquivos

Comparar o hash de um arquivo com o publicado prova que ele chegou igual, desde que a lista venha de um lugar confiável.

Quem publica um arquivo para download (um instalador, uma nota fiscal, a imagem de um sistema) costuma publicar junto o hash dele, a impressão digital de tamanho fixo do conceito Funções de hash. Quem baixa calcula o hash do que recebeu e compara com o publicado. Se forem iguais, o arquivo é o mesmo, byte por byte, que saiu de lá. Isso é conferir a integridade do arquivo.

Um exemplo trabalhado. A estância publica o arquivo recibo.txt, cujo conteúdo é Recibo 0099: 12 novilhos, e gera a lista de hashes com o sha256sum:

$ sha256sum recibo.txt
f79242f71858996c222d48675da84d7a723c824b9110fa5cb9749dea4871d88e  recibo.txt
$ sha256sum recibo.txt > SHA256SUMS

O SHA256SUMS tem uma linha por arquivo: o hash, dois espaços e o nome. Quem baixou confere com a opção -c (de check), que lê a lista, recalcula o hash de cada arquivo citado e compara:

$ sha256sum -c SHA256SUMS
recibo.txt: OK

Agora alguém troca 12 por 13 no recibo. Mudou um caractere, e o hash muda inteiro:

$ sha256sum recibo.txt
9e66adce0440b34e85bdc2e1b87c478e30f5bd7ea6cff630d00a654afa3e241d  recibo.txt
$ sha256sum -c SHA256SUMS
recibo.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
hash calculado publicado no site recibo como foi publicado Recibo 0099: 12 novilhos sha256sum f79242f7… OK igual recibo com 12 trocado por 13 Recibo 0099: 13 novilhos sha256sum 9e66adce… FAILED diferente SHA256SUMS f79242f7… recibo.txt a lista vem por outro caminho, fora do alcance de quem altera o arquivo
O recibo como foi publicado dá o hash f79242f7, igual ao da lista publicada no site, e o sha256sum -c diz OK; com 13 no lugar de 12, o hash vira 9e66adce, diferente, e sai FAILED.

O mesmo em Python, com o módulo hashlib:

import hashlib
real = hashlib.sha256(open('recibo.txt', 'rb').read()).hexdigest()
esperado = open('SHA256SUMS').read().split()[0]
print('OK' if real == esperado else 'FAILED')

No Windows, o PowerShell calcula o mesmo hash com Get-FileHash recibo.txt (em maiúsculas, o que não muda nada).

O que o hash garante. Que o arquivo é idêntico ao que gerou a linha da lista. Achar outro conteúdo com o mesmo SHA-256 é inviável, então nem um download corrompido nem uma troca de propósito passam despercebidos.

O que ele não garante.

  • Que a lista é verdadeira. Se quem altera o arquivo também consegue editar o SHA256SUMS, basta recalcular o hash e tudo dá OK. Por isso a lista vem por outro caminho, fora do alcance de quem mexe nos arquivos: o site oficial, com HTTPS, e não a mesma pasta.
  • Quem publicou. Para isso existe a assinatura digital: o publicador assina o SHA256SUMS com a chave privada dele, e qualquer um confere com a chave pública, por exemplo com gpg --verify SHA256SUMS.sig SHA256SUMS.
  • Que o conteúdo é bom. Um arquivo malicioso publicado de propósito tem um hash perfeitamente válido. O hash só diz que o arquivo chegou como saiu.

Boas práticas. Use SHA-256 ou maior: o MD5 e o SHA-1 já têm colisões fabricadas (dois arquivos diferentes com o mesmo hash) e não servem mais para isso. Compare os 64 símbolos, não só o começo, e prefira o sha256sum -c, que compara tudo e não se distrai.

Aparece nestes desafios