hashlib no Python: hashes seguros

Publicado em: 19/08/2026
Tempo de leitura: 6 minutos
Leitor de impressão digital representando verificação de hashes com hashlib no Python

O módulo hashlib oferece uma interface padronizada para funções hash criptográficas como SHA-256, SHA-512, SHA-3 e BLAKE2. Um hash transforma dados de tamanho arbitrário em um resumo de tamanho fixo. Pequenas mudanças na entrada produzem resultados muito diferentes, o que torna esses resumos úteis para verificar integridade, identificar conteúdo, deduplicar arquivos e construir protocolos de autenticação.

Apesar do nome “hash seguro”, escolher o algoritmo e o contexto corretos é essencial. SHA-256 pode verificar um download, mas não é suficiente para armazenar senhas. Um hash sem chave também não prova quem gerou a mensagem. Este guia mostra as APIs principais, processamento incremental, arquivos grandes, comparação segura, SHAKE, BLAKE2, PBKDF2 e scrypt.

Como um hash funciona

Uma função hash recebe bytes e produz um digest. A mesma entrada sempre gera a mesma saída. Não existe uma operação normal de “descriptografar” o hash para recuperar a mensagem. Porém, entradas previsíveis, como senhas comuns, podem ser testadas por força bruta. Por isso, irreversibilidade não significa proteção automática.

O primeiro passo é converter texto em bytes:

import hashlib

message = "Academify".encode("utf-8")
digest = hashlib.sha256(message)

print(digest.digest())
print(digest.hexdigest())

digest() devolve bytes binários. hexdigest() devolve texto hexadecimal, mais conveniente para bancos, manifests e logs. Para compreender a relação entre bytes e hexadecimal, consulte o guia de binascii no Python.

Qual algoritmo escolher?

Para novos sistemas, SHA-256 costuma ser uma escolha segura e interoperável para integridade. SHA-512 pode ser útil em protocolos que o especificam. SHA-3 é uma família com construção diferente da SHA-2. BLAKE2 é rápido, configurável e oferece modo com chave. SHAKE produz digests de comprimento variável.

MD5 e SHA-1 têm fraquezas de colisão conhecidas. Eles ainda aparecem em formatos legados e identificadores não adversariais, mas não devem proteger assinaturas, certificados ou conteúdo que um atacante possa manipular. O argumento usedforsecurity=False existe para indicar explicitamente um uso não relacionado à segurança em ambientes restritos; ele não torna o algoritmo mais forte.

print(sorted(hashlib.algorithms_guaranteed))
print("sha256" in hashlib.algorithms_available)

algorithms_guaranteed lista os algoritmos portáveis da biblioteca. algorithms_available depende também do OpenSSL usado pela instalação.

Atualização incremental

Você não precisa carregar todo o conteúdo na memória. Chamadas repetidas a update() são equivalentes ao hash da concatenação.

hasher = hashlib.sha256()
hasher.update(b"parte 1")
hasher.update(b"parte 2")
print(hasher.hexdigest())

Esse padrão é ideal para arquivos grandes, uploads e streams. Ele se relaciona diretamente às técnicas do artigo sobre leitura de arquivos gigantes.

Verificar um arquivo com SHA-256

from pathlib import Path
import hashlib

def sha256_file(path: Path, chunk_size: int = 1024 * 1024) -> str:
    hasher = hashlib.sha256()
    with path.open("rb") as file:
        while chunk := file.read(chunk_size):
            hasher.update(chunk)
    return hasher.hexdigest()

print(sha256_file(Path("pacote.zip")))

Compare o resultado com um valor obtido por um canal confiável. Se o arquivo e o hash vierem do mesmo servidor comprometido, a comparação não prova autenticidade. Para downloads, publique o digest por HTTPS e, quando o risco justificar, use uma assinatura digital.

Arquivos compactados também podem conter checksums internos, mas eles normalmente detectam corrupção acidental. Veja o guia para criar ZIP com Python e diferencie CRC de hash criptográfico.

hashlib.file_digest()

Desde Python 3.11, file_digest() simplifica o hash de um arquivo binário e pode usar caminhos de I/O otimizados.

with open("pacote.zip", "rb") as file:
    digest = hashlib.file_digest(file, "sha256")

print(digest.hexdigest())

Depois da chamada, considere a posição e o estado do arquivo desconhecidos e feche-o normalmente. No Python 3.14, um arquivo em modo não bloqueante gera BlockingIOError; versões anteriores podiam produzir um digest incorreto com bytes nulos espúrios.

Comparar digests corretamente

Para uma verificação simples de arquivo, uma comparação comum costuma ser suficiente. Em autenticação e segredos, use hmac.compare_digest(), que reduz vazamentos de tempo relacionados ao ponto da primeira diferença.

import hmac

expected = "a" * 64
calculated = sha256_file(Path("pacote.zip"))

if not hmac.compare_digest(expected, calculated):
    raise ValueError("Arquivo não corresponde ao digest esperado")

Uma comparação constante não corrige um protocolo mal projetado. O valor esperado ainda precisa ser autêntico e o algoritmo deve ser adequado.

SHAKE com tamanho variável

shake_128 e shake_256 exigem que você informe o número de bytes do resultado.

token_id = hashlib.shake_256(b"registro-123").hexdigest(20)
print(token_id)  # 40 caracteres hexadecimais

Defina o tamanho com base na segurança e na probabilidade de colisão exigidas. Não encurte digests arbitrariamente em identificadores expostos a entrada adversarial.

BLAKE2 e personalização

BLAKE2b é otimizado para plataformas de 64 bits e permite resultados de 1 a 64 bytes. BLAKE2s produz até 32 bytes e é adequado a plataformas menores. O parâmetro person separa domínios: a mesma entrada usada para finalidades diferentes gera digests diferentes.

file_hash = hashlib.blake2b(
    b"conteudo",
    digest_size=32,
    person=b"Files-v1",
).hexdigest()

block_hash = hashlib.blake2b(
    b"conteudo",
    digest_size=32,
    person=b"Blocks-v1",
).hexdigest()

assert file_hash != block_hash

BLAKE2 também possui modo com chave, útil para autenticação de mensagens. Ainda assim, HMAC é mais conhecido e costuma ser preferível quando interoperabilidade e revisão de segurança são prioridades.

Senhas: por que SHA-256 sozinho é errado?

Hashes gerais são rápidos. Essa característica é ótima para arquivos, mas permite que atacantes testem milhões de senhas por segundo. Para credenciais, use Argon2id, scrypt, bcrypt ou PBKDF2 com salt aleatório e custo calibrado.

O artigo sobre hash de senhas em Python explica o fluxo completo. Não reutilize exemplos de SHA-256 puro para autenticação.

PBKDF2 com salt

import os
import hashlib
import hmac

salt = os.urandom(16)
iterations = 600_000
password = "senha longa".encode("utf-8")

derived = hashlib.pbkdf2_hmac(
    "sha256",
    password,
    salt,
    iterations,
)

# Armazene algoritmo, iterações, salt e derived.

O número ideal de iterações depende do hardware e precisa ser medido. A autenticação deve ser lenta o suficiente para dificultar ataques, mas aceitável para usuários. Imponha limite ao tamanho da senha antes de executar a derivação.

scrypt e custo de memória

hashlib.scrypt() adiciona custo de memória, dificultando paralelização em hardware especializado.

derived = hashlib.scrypt(
    password,
    salt=salt,
    n=2**14,
    r=8,
    p=1,
    dklen=32,
)

Os parâmetros devem ser calibrados e armazenados junto ao hash. Trate ValueError e erros de memória como falhas controladas, sem reduzir silenciosamente a segurança.

Hashes para deduplicação e cache

Um digest pode identificar conteúdo em caches e pipelines. Inclua no hash todas as opções que afetam o resultado para evitar colisões semânticas.

def cache_key(url: str, language: str) -> str:
    canonical = f"v1\n{language}\n{url}".encode("utf-8")
    return hashlib.sha256(canonical).hexdigest()

Ao integrar APIs, normalize cuidadosamente a entrada e nunca use um hash para esconder segredos. O guia de consumo de APIs REST mostra práticas de validação e transporte.

Erros comuns

Os erros mais frequentes são passar str sem codificar, usar MD5 ou SHA-1 em segurança, confundir hash com criptografia, usar SHA-256 puro para senhas, comparar MACs com ==, confiar em um digest recebido pelo mesmo canal inseguro e carregar arquivos enormes na memória.

Boas práticas

Use SHA-256 ou algoritmo moderno definido pelo protocolo. Processe dados em blocos. Registre o nome e a versão do esquema junto ao digest. Separe integridade de autenticidade. Use HMAC ou assinatura quando precisar provar origem. Para senhas, use uma KDF lenta com salt e parâmetros armazenados. Nunca invente uma construção criptográfica própria.

Conclusão

hashlib cobre desde hashes simples de arquivos até SHA-3, SHAKE, BLAKE2, PBKDF2 e scrypt. O módulo é fácil de usar, mas o contexto determina a segurança. Um digest pode detectar alterações; uma mensagem autenticada precisa de chave; uma senha precisa de derivação lenta; e um download confiável precisa de um valor esperado obtido com autenticidade.

Consulte a documentação oficial de hashlib e a publicação FIPS 180-4 do NIST.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código binário projetado representando conversões com binascii no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    binascii no Python: binário e ASCII

    Aprenda binascii no Python para converter hexadecimal, Base64 e quoted-printable, calcular CRC e validar dados binários com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    codecs no Python: domine encodings

    Aprenda codecs no Python para trabalhar com encodings, handlers de erro, BOM, streams incrementais e migrar codecs.open para open.

    Ler mais

    Tempo de leitura: 7 minutos
    18/08/2026
    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    base64 no Python: codifique dados

    Aprenda base64 no Python para codificar bytes, usar Base64 URL-safe, validar padding, aplicar limites e diferenciar encoding de criptografia.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    urllib.parse no Python: manipule URLs

    Aprenda urllib.parse no Python para decompor URLs, criar queries, codificar componentes e evitar riscos com urljoin, redirects e SSRF.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ipaddress no Python: redes IPv4 e IPv6

    Aprenda ipaddress no Python para validar IPv4 e IPv6, calcular redes CIDR, dividir sub-redes e criar políticas de acesso seguras.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    A vibrant collection of blue sewing threads arranged with hands on a white background.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    queue no Python: coordene threads

    Aprenda queue no Python para coordenar threads com FIFO, prioridade, backpressure, task_done, join, retries e shutdown seguro.

    Ler mais

    Tempo de leitura: 5 minutos
    17/08/2026