Ir para o conteúdo

Funções hash criptográficas

Um guia voltado à verificação de funções hash criptográficas, abrangendo propriedades de segurança, codificação de bytes, SHA-2, SHA-3, Keccak, usos em blockchain e riscos de implementação.

Atualizado

Somente para fins educacionais; não constitui aconselhamento de investimento nem de implementação criptográfica. A correspondência de um resumo, por si só, não comprova autenticidade, propriedade, autorização, finalidade ou disponibilidade dos dados.

Resposta direta

Uma função hash criptográfica mapeia de forma determinística uma mensagem representada como bytes para um resumo com comprimento de saída definido. Para um hash de comprimento fixo de n bits, a relação básica é:

h = H(m), where h is in {0,1}^n

Os mesmos bytes e o mesmo algoritmo produzem o mesmo resumo. A alteração de um bit na entrada deve mudar de maneira imprevisível muitos bits da saída, mas esse efeito avalanche não é a definição de segurança. Os principais objetivos de segurança são a resistência à pré-imagem (dado um resumo, é inviável encontrar uma entrada que o produza), a resistência à segunda pré-imagem (dada uma entrada, é inviável encontrar outra entrada com o mesmo resumo) e a resistência a colisões (é inviável encontrar duas entradas distintas quaisquer com o mesmo resumo).

Hashing não é criptografia: não há chave de descriptografia nem promessa de que a entrada possa ser recuperada. Como uma quantidade infinita de mensagens possíveis é mapeada para um espaço de saída finito, colisões necessariamente existem; segurança significa que encontrar uma colisão útil é computacionalmente inviável para o algoritmo e o comprimento de saída escolhidos.

Um resumo também não fornece autenticidade por si só. Recalcular o hash de um arquivo só detecta uma divergência quando o resumo esperado e o algoritmo foram obtidos por um canal confiável. Os protocolos alcançam garantias mais fortes ao combinar hashes com assinaturas, códigos de autenticação de mensagem, estruturas de dados autenticadas, regras de consenso ou prova de trabalho.

Como funciona

  1. Defina os bytes exatos. A codificação do texto, o uso de maiúsculas, os espaços em branco, a ordem dos campos, a representação de inteiros, os prefixos de comprimento e a serialização afetam m. Um protocolo deve especificar uma codificação canônica e vincular o hash a um algoritmo, uma versão, uma rede e uma finalidade.
  2. Execute a construção especificada. O SHA-256 pré-processa uma mensagem de comprimento limitado, divide-a em blocos e atualiza iterativamente um estado interno. O SHA3-256 usa uma construção esponja baseada em KECCAK. Ambos retornam resumos de 256 bits, mas são funções diferentes e não produzem saídas intercambiáveis.
  3. Interprete a segurança de acordo com a propriedade exigida. Para um hash ideal de n bits, uma busca genérica de pré-imagem exige cerca de 2^n avaliações, enquanto uma busca genérica de colisão exige cerca de 2^(n/2) por causa do efeito aniversário. O comprimento da saída não basta se o algoritmo estiver comprometido, o resumo for truncado ou o protocolo ao redor apresentar falhas.
  4. Construa o protocolo em torno do resumo. Um esquema de assinatura digital pode assinar o resumo de uma mensagem; o HMAC acrescenta uma chave secreta para autenticação de mensagens; uma árvore de Merkle compromete muitas folhas com uma única raiz; e a prova de trabalho calcula repetidamente o hash de cabeçalhos de bloco candidatos até que um resumo satisfaça um alvo. Essas construções oferecem garantias diferentes.
  5. Use a função exata da blockchain. Os cabeçalhos de bloco e os nós de Merkle do Bitcoin usam SHA-256 duplo na ordem de bytes especificada. A execução do Ethereum usa Keccak-256, proveniente do projeto KECCAK anterior à padronização, e não o SHA3-256 padronizado. Portanto, um rótulo como “hash de 256 bits” é insuficiente para a verificação.
  6. Verifique o contexto antes de atribuir significado. Confira a origem do resumo esperado, o identificador do algoritmo, a codificação dos bytes, o domínio ou a blockchain, a referência de bloco e de estado, o status de confirmação e qualquer truncamento. Um cálculo correto no contexto errado continua sendo uma verificação malsucedida.

Exemplos práticos

  • Uma pequena alteração na entrada. O SHA-256 dos cinco bytes UTF-8 de hello é 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824. Substituir o primeiro byte pelo H maiúsculo resulta em 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969. Os resumos diferentes não revelam qual byte mudou.
  • A força de segurança não equivale ao comprimento do resumo em todos os modelos de ataque. Um hash ideal de 256 bits oferece aproximadamente 2^256 operações de resistência à pré-imagem, mas 2^128 contra colisões. Essa distinção importa quando um protocolo depende da resistência a colisões, como costuma ocorrer em fluxos de assinatura digital.
  • Uma prova de Merkle autentica a inclusão em relação a uma única raiz. O verificador calcula o hash da folha codificada com cada nó irmão fornecido, na ordem especificada, até reconstruir a raiz comprometida. Uma correspondência não prova que a raiz é definitiva, que os dados da folha são verdadeiros ou que os dados omitidos estão disponíveis.
  • A prova de trabalho acrescenta uma regra de alvo. O Bitcoin só valida um cabeçalho candidato quando seu valor de SHA-256 duplo, interpretado segundo as regras de consenso, é menor ou igual ao alvo codificado. O resumo não se torna mais resistente a colisões porque os mineradores realizaram mais trabalho.

Riscos

  • Usar um algoritmo obsoleto ou inadequado, especialmente confiar no SHA-1 quando é necessária resistência a colisões.
  • Tratar SHA3-256, Keccak-256, SHA-256, SHA-256 duplo e variantes truncadas de formas diferentes como se fossem intercambiáveis.
  • Calcular o hash do texto exibido em vez dos bytes canônicos ou ignorar a normalização Unicode, os espaços em branco, a ordem dos bytes, a ordem dos campos e a codificação do comprimento.
  • Baixar um arquivo e seu resumo esperado do mesmo local comprometido, o que não fornece uma verificação de integridade independente.
  • Usar diretamente um hash rápido de uso geral para armazenar senhas, em vez de um esquema de hash de senhas com sal, criado para essa finalidade e com um fator de trabalho adequado.
  • Usar H(secret || message) como código de autenticação improvisado; algumas construções de hash iterativas permitem ataques de extensão de comprimento, enquanto o HMAC foi projetado para autenticação com chave.
  • Truncar resumos sem calcular a segurança resultante contra colisões e pré-imagens para a escala e o modelo de ameaças do protocolo.
  • Reutilizar uma codificação entre protocolos sem separação de domínios, permitindo que um resumo válido em um contexto seja interpretado em outro.
  • Presumir que o hash de uma transação comprova confirmação, finalidade, execução bem-sucedida, propriedade ou ausência de reorganização da blockchain.
  • Presumir que um hash de conteúdo torna os dados referenciados recuperáveis; um compromisso pode continuar válido mesmo que todas as cópias disponíveis desapareçam.
  • Comparar strings de exploradores sem verificar a ordem dos bytes, as regras de prefixo, a serialização ou se a interface exibe um identificador interno de outra forma.
  • Implementar primitivas criptográficas sem vetores de teste padronizados, bibliotecas mantidas, revisão independente e procedimentos de atualização.

Erros comuns

  • Um hash é um dado criptografado. A criptografia é reversível com a chave apropriada; um hash criptográfico é um resumo unidirecional sem operação de descriptografia.
  • Entradas diferentes nunca podem compartilhar um resumo. As colisões necessariamente existem para uma saída de comprimento fixo. Um projeto seguro faz com que seja inviável encontrá-las e explorá-las.
  • Um resumo de 256 bits sempre fornece 256 bits de segurança. A resistência genérica a colisões é de cerca de 128 bits para um hash ideal de 256 bits, e as escolhas do protocolo podem reduzi-la ainda mais.
  • Hashes correspondentes comprovam quem criou a mensagem. Um hash simples não contém segredo nem autentica remetente algum; use uma assinatura ou um MAC adequado quando a origem for relevante.
  • Keccak-256 e SHA3-256 são dois nomes para a mesma função. Eles usam projetos estreitamente relacionados, mas parâmetros de padronização diferentes, e produzem resumos distintos.
  • O hash de uma transação on-chain comprova a liquidação. Ele identifica os dados codificados da transação; inclusão na blockchain, status de execução, confirmações e finalidade são fatos separados.

Tópicos relacionados

Fontes

Navegação

Pesquisar na wiki...