O Que Torna um Formato de Armazenamento Recuperável
Quatro formatos de armazenamento, classificados por recuperabilidade:
| Formato | Recuperável? | Exemplo | Método de Recuperação |
|---|---|---|---|
| Texto Simples | Sim | password: hunter2 | Ler o arquivo |
| Base64 | Sim | cGFzc3dvcmQ= | base64 --decode |
| Cifra reversível (AES) | Sim | ENC[AES256:...] | Descriptografar com a chave |
| Hash unidirecional (bcrypt) | Não | $2b$12$... | Não pode ser revertido; deve-se usar força bruta |
Texto simples, base64 e cifra reversível: todos recuperáveis. Um único dump do banco de dados de credenciais dá ao atacante todas as senhas em texto claro, para todos os usuários, simultaneamente. Uma violação; exposição total.
O Exemplo do Mailman 2.x
Mailman 2.x (gerenciador de listas de discussão GNU): armazenava as senhas dos inscritos em texto simples. E-mail mensal de lembrete de senha: enviava a todos os inscritos sua senha em texto claro. Dois defeitos separados, ambos MOAD-0006:
1. Armazenamento: texto simples no banco de dados da lista. Um comprometimento do servidor expõe todas as senhas dos inscritos.
2. Transmissão: o e-mail mensal envia a senha em texto simples via SMTP para o servidor de e-mail do inscrito. O e-mail trafega em texto claro por múltiplos saltos SMTP.
A equipe do Mailman projetou ambos os comportamentos. A recuperação era o recurso: os assinantes podiam recuperar senhas esquecidas. O nome Glass Safe vem disso: o cofre mantém as credenciais em forma visível. Qualquer pessoa que alcance o cofre pode ler todo o conteúdo simultaneamente.
O Princípio do Já-Roubado
Uma credencial armazenada em forma recuperável é uma credencial já roubada. O atacante ainda não chegou. A violação ainda não aconteceu. Mas a arquitetura garante: quando uma violação ocorre, todas as credenciais caem simultaneamente. Nenhuma violação ocorre isoladamente; toda credencial no armazenamento recuperável é transferida para o atacante na mesma operação.
MOAD-0006 vs MOAD-0004
MOAD-0004 (Segredo Registrado): credenciais escritas em logs acidentalmente. A escrita no log não era a intenção; foi um efeito colateral da ativação do registro de cabeçalhos para depuração.
MOAD-0006 (Glass Safe): credenciais armazenadas em forma recuperável por design. A recuperação era a intenção. O recurso de lembrete de senha exigia armazenar a senha. O recurso de exibir senha exigia armazená-la. O compromisso arquitetural com a recuperação criou o defeito.
Distinção em uma linha: MOAD-0004 coloca credenciais em logs por acidente; MOAD-0006 armazena credenciais em forma recuperável de propósito. As correções operam em camadas diferentes.
Estrutural vs Acidental
A distinção arquitetural entre MOAD-0006 e MOAD-0004 determina a estratégia de correção. Um log escrito acidentalmente: corrija a camada de serialização. Um armazenamento projetado para recuperação: redesenhe o recurso que exigia recuperação.
Por que o bcrypt Funciona
Uma função de hash unidirecional aceita uma senha e produz um resumo de comprimento fixo. Dado o resumo, a senha original não pode ser recuperada. Não é 'difícil de recuperar': é impossível reverter. A função executa em uma única direção.
Três propriedades necessárias para o armazenamento de credenciais:
1. Unidirecional (resistência à pré-imagem). Dado hash(password), nenhum algoritmo recupera password mais rápido que a força bruta. bcrypt, scrypt e argon2 satisfazem essa propriedade.
2. Salt. Um valor aleatório adicionado antes da senha antes do hash. Mesma senha, salt diferente, hash diferente. Objetivo: derrotar tabelas arco-íris (dicionários de hashes pré-computados). Sem salt: um atacante calcula hash('password123') uma vez e verifica todos os 1 milhão de usuários simultaneamente. Com salt: cada usuário tem um hash único mesmo para a mesma senha.
3. Lento por design. bcrypt aceita um fator de trabalho. Fator de trabalho maior: mais iterações, mais tempo de computação por tentativa de hash. Login: 300ms para calcular o hash uma vez. Aceitável. Força bruta: 300ms por tentativa. Em 1 bilhão de tentativas: 9,5 anos por senha. Inaceitável para um atacante. A lentidão: um recurso, não um defeito.
import bcrypt
# Armazenar: hash unidirecional com salt
def store_password(plaintext: str) -> bytes:
return bcrypt.hashpw(plaintext.encode(), bcrypt.gensalt(rounds=12))
# Verificar: calcular o hash do candidato e comparar os resumos
def verify_password(plaintext: str, stored_hash: bytes) -> bool:
return bcrypt.checkpw(plaintext.encode(), stored_hash)
# NUNCA armazenado: a senha em texto simples
# NUNCA recuperado: o texto simples do hash
# Redefinição de senha, não lembrete de senha
A Compensação
O hash unidirecional torna a recuperação de senha impossível. Um usuário que esquece sua senha não pode recebê-la de volta. Um e-mail de lembrete de senha não pode existir. A experiência do usuário muda: 'esqueceu sua senha? redefina-a.' Não é uma degradação: é um limite de segurança. O sistema que não pode recuperar uma senha não pode vazar uma senha.
Uma violação de banco de dados que expõe hashes bcrypt: todos os hashes visíveis, nenhuma senha visível. Um atacante deve forçar cada hash individualmente, a 300ms por tentativa, com salt por usuário derrotando tabelas pré-computadas. Uma violação que expõe senhas em texto simples: exposição total imediata.
Criptografia Forte Não É Suficiente
Uma auditoria de segurança identifica um sistema de armazenamento de credenciais. As senhas são armazenadas usando criptografia AES-256-CBC com uma chave no lado do servidor. O relatório de auditoria o sinaliza como um defeito de Glass Safe.
A equipe de engenharia responde: 'AES-256 é o cifrador simétrico mais forte disponível. A chave reside em um módulo de segurança de hardware. Nenhum atacante consegue descriptografar essas senhas.'