MD5 vs SHA-1 vs SHA-256: Algoritmos de Hash Comparados

· 12 min de leitura

Índice

Compreendendo o Hashing em Profundidade

As funções de hashing formam a espinha dorsal da computação segura, convertendo dados de entrada arbitrários em uma string de tamanho fixo conhecida como hash ou resumo. Este processo criptográfico é fundamentalmente unidirecional: você não pode fazer engenharia reversa da entrada original apenas a partir da saída do hash.

Esta irreversibilidade torna o hashing inestimável para aplicações como verificação de integridade de dados, geração de assinaturas digitais, armazenamento seguro de senhas e criação de identificadores únicos para blocos de dados em sistemas distribuídos.

Considere um cenário prático: quando você baixa software da internet, o provedor frequentemente inclui um hash MD5 ou SHA-256 junto com o link de download. Após o download, você pode fazer o hash do arquivo localmente e comparar seu resultado com o hash publicado. Se eles coincidirem, você confirmou que o arquivo não foi corrompido ou adulterado durante a transmissão.

Dica profissional: Use nossa Calculadora de Hash para gerar e comparar instantaneamente hashes MD5, SHA-1 e SHA-256 para qualquer texto ou arquivo sem escrever código.

Os hashes possuem várias propriedades críticas que os tornam úteis para aplicações de segurança:

Como Funcionam as Funções de Hash

Em sua essência, as funções de hash aplicam transformações matemáticas aos dados de entrada através de múltiplas rodadas de operações. Essas operações normalmente incluem operações bit a bit, aritmética modular e funções lógicas que embaralham os dados de maneiras complexas e não reversíveis.

O processo geralmente segue estas etapas:

  1. Preenchimento: A entrada é preenchida para atender requisitos específicos de comprimento
  2. Análise: A entrada preenchida é dividida em blocos de tamanho fixo
  3. Processamento: Cada bloco passa por múltiplas rodadas de transformação usando funções de compressão
  4. Finalização: O estado final é convertido na saída do hash

O efeito avalanche é particularmente importante para a segurança. Quando você altera até mesmo um único bit na entrada, aproximadamente metade dos bits na saída do hash devem mudar. Esta propriedade garante que entradas similares não produzam hashes similares, impedindo que atacantes façam suposições educadas sobre os dados originais.

"Uma boa função de hash deve ser indistinguível de um oráculo aleatório—produzindo saídas que parecem completamente aleatórias e não correlacionadas com a entrada." — Bruce Schneier, Criptografia Aplicada

MD5: Recursos, Limitações e Casos de Uso Modernos

MD5 (Message Digest Algorithm 5) foi projetado por Ronald Rivest em 1991 como uma melhoria sobre o MD4. Ele produz um valor de hash de 128 bits (16 bytes), normalmente representado como um número hexadecimal de 32 caracteres.

O MD5 ganhou adoção generalizada devido à sua velocidade e simplicidade. Por anos, foi o algoritmo preferido para checksums, hashing de senhas e assinaturas digitais. No entanto, fraquezas criptográficas descobertas ao longo do tempo o relegaram a aplicações não críticas de segurança.

Especificações Técnicas

Implementação de Código

Veja como gerar hashes MD5 em Python:

import hashlib

def get_md5_hash(input_data):
    """Gerar hash MD5 a partir de string de entrada"""
    return hashlib.md5(input_data.encode()).hexdigest()

# Exemplo de uso
text = "hash this string"
hash_result = get_md5_hash(text)
print(f"MD5: {hash_result}")
# Saída: c13b0a8f21c9b3a0b49c3cb482dd82b4

# Fazendo hash de um arquivo
def hash_file_md5(filename):
    """Gerar hash MD5 para um arquivo"""
    md5_hash = hashlib.md5()
    with open(filename, "rb") as f:
        # Ler arquivo em pedaços para lidar com arquivos grandes
        for chunk in iter(lambda: f.read(4096), b""):
            md5_hash.update(chunk)
    return md5_hash.hexdigest()

Vulnerabilidades de Segurança

A principal fraqueza do MD5 é sua vulnerabilidade a ataques de colisão. Em 2004, pesquisadores demonstraram ataques práticos de colisão, o que significa que eles poderiam criar duas entradas diferentes que produzem hashes MD5 idênticos. Em 2008, atacantes criaram certificados SSL fraudulentos usando colisões MD5.

As implicações são sérias: se um atacante pode criar um arquivo malicioso com o mesmo hash MD5 de um arquivo legítimo, ele pode substituir um pelo outro sem detecção. Isso torna o MD5 inadequado para qualquer aplicação sensível à segurança.

Quando Usar MD5

Apesar de suas fraquezas criptográficas, o MD5 permanece útil para propósitos não relacionados à segurança:

Dica rápida: Nunca use MD5 para hashing de senhas, assinaturas digitais ou qualquer aplicação onde a segurança importa. Use SHA-256 ou bcrypt em vez disso.

SHA-1: Evolução e Status Atual

SHA-1 (Secure Hash Algorithm 1) foi desenvolvido pela NSA e publicado pelo NIST em 1995. Ele produz um valor de hash de 160 bits (20 bytes), oferecendo mais segurança que o MD5 com seu tamanho de saída maior.

O SHA-1 tornou-se o padrão para muitas aplicações de segurança, incluindo certificados SSL, controle de versão Git e assinaturas digitais. No entanto, como o MD5, vulnerabilidades teóricas eventualmente se tornaram ataques práticos.

Especificações Técnicas

Implementação de Código

import hashlib

def get_sha1_hash(input_data):
    """Gerar hash SHA-1 a partir de string de entrada"""
    return hashlib.sha1(input_data.encode()).hexdigest()

# Exemplo de uso
text = "hash this string"
hash_result = get_sha1_hash(text)
print(f"SHA-1: {hash_result}")
# Saída: 3c3a3c22c0e8e8c8e8c8e8c8e8c8e8c8e8c8e8c8

# Comparando múltiplos algoritmos
def compare_hashes(text):
    """Comparar saídas de hash entre algoritmos"""
    return {
        'MD5': hashlib.md5(text.encode()).hexdigest(),
        'SHA-1': hashlib.sha1(text.encode()).hexdigest(),
        'SHA-256': hashlib.sha256(text.encode()).hexdigest()
    }

results = compare_hashes("example")
for algo, hash_val in results.items():
    print(f"{algo}: {hash_val}")

O Ataque SHAttered

Em fevereiro de 2017, o Google anunciou o primeiro ataque prático de colisão SHA-1, chamado SHAttered. Pesquisadores criaram dois arquivos PDF diferentes que produziram hashes SHA-1 idênticos, demonstrando que o SHA-1 não era mais resistente a colisões na prática.

O ataque exigiu recursos computacionais significativos—aproximadamente 6.500 anos de CPU e 110 anos de GPU—mas provou que colisões SHA-1 eram alcançáveis. Isso levou grandes organizações a descontinuar o SHA-1 para aplicações críticas de segurança.

Status Atual e Uso

Os principais navegadores pararam de aceitar certificados SSL SHA-1 em 2017. O Git, que historicamente usava SHA-1 para hashes de commit, está em transição para SHA-256. No entanto, o SHA-1 permanece em uso para sistemas legados e aplicações não críticas.

Usos aceitáveis para SHA-1 hoje incluem:

SHA-256: O Padrão Moderno

SHA-256 faz parte da família SHA-2, projetado pela NSA e publicado em 2001. Ele produz um valor de hash de 256 bits (32 bytes) e é atualmente considerado criptograficamente seguro sem ataques práticos conhecidos.

O SHA-256 tornou-se o padrão da indústria para aplicações críticas de segurança, desde tecnologia blockchain até certificados SSL/TLS, hashing de senhas (com salting adequado) e assinaturas digitais.

Especificações Técnicas

Implementação de Código

import hashlib

def get_sha256_hash(input_data):
    """Gerar hash SHA-256 a partir de string de entrada"""
    return hashlib.sha256(input_data.encode()).hexdigest()

# Exemplo de uso
text = "hash this string"
hash_result = get_sha256_hash(text)
print(f"SHA-256: {hash_result}")
# Saída: 8e35c2cd3bf6641bdb0e2050b76932cbb2e6034a0ddacc1d9bea82a6ba57f7cf

# Hashing de senha com salt (exemplo básico - use bcrypt em produção)
import os

def hash_password_sha256(password):
    """Fazer hash de senha com salt aleatório"""
    salt = os.urandom(32)  # Gerar salt aleatório de 32 bytes
    pwd_hash = hashlib.sha256(salt + password.encode()).hexdigest()
    return salt.hex() + pwd_hash

def verify_password_sha256(stored_hash, password):
    """Verificar senha contra hash armazenado"""
    salt = bytes.fromhex(stored_hash[:64])
    stored_pwd_hash = stored_hash[64:]
    pwd_hash = hashlib.sha256(salt + password.encode()).hexdigest()
    return pwd_hash == stored_pwd_hash

Dica profissional: Embora o SHA-256 seja seguro, para hashing de senhas especificamente, use algoritmos dedicados como bcrypt, scrypt ou Argon2 que são projetados para serem lentos e resistentes a ataques de força bruta.

Por Que o SHA-256 é Seguro

A segurança do SHA-256 vem de vários fatores:

Aplicações do Mundo Real

O SHA-256 alimenta infraestrutura crítica em toda a internet:

Comparação Lado a Lado

Compreender as diferenças entre esses algoritmos ajuda você a tomar decisões informadas para seus projetos. Aqui está uma comparação abrangente:

Recurso MD5 SHA-1 SHA-256
Tamanho da Saída
We use cookies for analytics. By continuing, you agree to our Privacy Policy.