Por que entropia e aleatoriedade importam na prática
Em criptografia aplicada, muitos mecanismos “quebram” não porque o algoritmo é fraco, mas porque a aleatoriedade usada para gerar chaves, nonces, IVs, desafios e tokens é previsível ou repetida. Entropia é a medida da incerteza (imprevisibilidade) disponível para um atacante. Um gerador de números aleatórios criptograficamente seguro (CSPRNG) é um componente que transforma entropia em uma sequência de bits que deve ser indistinguível de aleatória para quem não conhece seu estado interno.
Do ponto de vista operacional, você quase nunca “gera aleatoriedade do nada”: você coleta entropia de fontes físicas/ambientais, alimenta um CSPRNG, e então usa a saída para fins criptográficos. Falhas comuns incluem: usar funções pseudoaleatórias não criptográficas (ex.: PRNG de propósito geral), reutilizar nonces/IVs, inicializar geradores com sementes de baixa entropia (tempo, PID), ou depender de fontes que parecem aleatórias mas são controláveis (movimento do mouse em VM, relógio previsível, contadores).
Conceito de entropia: intuição e quantificação
Entropia como “tamanho do espaço de busca”
Uma forma prática de pensar: se um segredo tem N bits de entropia, um atacante precisa, em média, testar cerca de 2^(N-1) possibilidades para adivinhar. Se você gera um token com 32 bits de entropia, isso é aproximadamente 4 bilhões de possibilidades; parece muito, mas pode ser exaurido rapidamente em ataques online distribuídos ou em ataques offline dependendo do contexto.
Min-entropia e pior caso
Em segurança, costuma-se usar min-entropia, que foca no evento mais provável. Se um gerador às vezes produz valores com viés (alguns valores saem com probabilidade maior), a min-entropia captura o pior caso. Em termos simples: não basta “parecer aleatório”; o valor mais provável não pode ser “provável demais”.
Entropia não é “comprimento”
Um erro recorrente é confundir “tamanho em bits” com entropia. Um UUID textual pode ter 128 bits de comprimento, mas se for derivado de timestamp e MAC address (ou outra estrutura previsível), a entropia real pode ser muito menor. Da mesma forma, um token base64 longo pode ser apenas um contador codificado.
Continue em nosso aplicativo
Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.
ou continue lendo abaixo...Baixar o aplicativo
Fontes de entropia: o que realmente alimenta um CSPRNG
Fontes físicas e ambientais
Fontes típicas incluem ruído de hardware (TRNG), jitter de temporização, variações de latência de interrupções, ruído térmico, eventos de dispositivos, e em alguns sistemas, instruções de CPU que expõem entropia coletada por hardware. Essas fontes podem ser boas, mas precisam ser tratadas como “ruidosas”: podem falhar, ficar previsíveis em ambientes virtualizados, ou ser influenciadas por um atacante com acesso ao ambiente.
Ambientes virtualizados e containers
Em VMs e containers, especialmente em boot inicial, há risco de baixa entropia: poucos eventos, relógio sincronizado, pouca variação de interrupções. Isso pode levar a sementes fracas e, consequentemente, chaves ou nonces repetidos entre instâncias clonadas. Em cenários de auto-scaling, imagens idênticas iniciando ao mesmo tempo podem produzir padrões se o sistema não tiver um mecanismo robusto de inicialização do CSPRNG.
TRNG vs CSPRNG: papéis diferentes
TRNG (gerador verdadeiramente aleatório) tenta extrair aleatoriedade diretamente de fenômenos físicos. CSPRNG expande uma semente (seed) em muitos bits pseudoaleatórios com propriedades criptográficas. Na prática, você quer: (1) coleta de entropia suficiente, (2) um CSPRNG bem projetado, (3) re-semeadura (reseeding) periódica/por eventos, e (4) isolamento de estado para evitar vazamentos.
O pipeline recomendado: coletar, misturar, expandir, usar
1) Coleta de entropia
O sistema operacional normalmente oferece uma API para obter bytes aleatórios adequados para criptografia. A recomendação prática é: use a API do SO e evite implementar seu próprio coletor. O SO costuma combinar múltiplas fontes, estimar entropia e manter um estado interno protegido.
2) Mistura (conditioning)
“Misturar” significa aplicar um extrator/condicionador para reduzir vieses e tornar a saída robusta mesmo se algumas fontes forem fracas. Isso pode envolver funções criptográficas internas do subsistema de aleatoriedade do SO. O objetivo é que, se ao menos uma fonte tiver entropia real e não for controlada pelo atacante, a mistura gere um estado imprevisível.
3) Expansão com CSPRNG
Depois de ter um estado inicial com entropia, o CSPRNG gera quantos bytes forem necessários. Um bom CSPRNG deve oferecer: resistência a previsão (next-bit unpredictability), resistência a comprometimento parcial do estado, e capacidade de recuperação após reseeding.
4) Uso correto (nonces, IVs, tokens, chaves)
Nem tudo precisa do mesmo tipo de aleatoriedade. Alguns valores precisam ser imprevisíveis (ex.: chaves, tokens de sessão). Outros precisam ser únicos (ex.: nonces em certos esquemas), e podem ser determinísticos desde que garantam unicidade. O erro é tratar “único” como “aleatório” ou vice-versa, sem checar o requisito do mecanismo.
Passo a passo prático: como gerar bytes aleatórios com segurança
O passo a passo abaixo é intencionalmente focado em decisões e validações, não em detalhes de capítulos anteriores.
Passo 1: identifique o requisito do valor
Chave criptográfica: precisa ser imprevisível e com entropia suficiente para o nível de segurança desejado.
Token de autenticação/sessão: imprevisível; deve resistir a adivinhação online e a vazamento parcial.
Nonce/IV: muitas construções exigem unicidade; algumas exigem imprevisibilidade. Leia o requisito do esquema específico e trate “repetição” como falha crítica.
Salt: tipicamente precisa ser único e não secreto; ainda assim, deve ser gerado com boa aleatoriedade para evitar colisões e padrões.
Passo 2: use a API do sistema operacional
Em vez de PRNGs de bibliotecas gerais, use o gerador criptográfico do SO. Exemplos de uso típico:
// Pseudocódigo (independente de linguagem) para obter N bytes aleatórios do SO
bytes = OS_CSPRNG(N)
if bytes falhar: abortar operação sensívelCritérios práticos:
Trate falha de obtenção de aleatoriedade como erro fatal para operações que dependem disso (geração de chave, token, nonce crítico).
Evite “fallback” para tempo, PID, contador, ou qualquer fonte previsível.
Evite inicializar manualmente seeds para geradores criptográficos quando a biblioteca já integra com o SO.
Passo 3: codifique para transporte sem reduzir entropia
Ao serializar bytes aleatórios para texto (URLs, cabeçalhos, JSON), use codificações que preservem os bits (base64url, hex). O cuidado é não truncar demais. Exemplo: se você precisa de 128 bits de entropia, gere 16 bytes e então codifique; não gere uma string “de 16 caracteres” achando que isso equivale a 128 bits.
// Exemplo de cálculo prático
// 16 bytes = 128 bits
// hex: 32 caracteres
// base64: ~24 caracteres (com padding), base64url semelhantePasso 4: registre metadados, não segredos
Para depuração, registre apenas informações não sensíveis: tamanho do token, algoritmo de codificação, e contexto. Nunca registre o valor aleatório em si (chaves, seeds, tokens). Logs são um vetor frequente de vazamento.
Testes de aleatoriedade: o que eles dizem e o que não dizem
Testes estatísticos não provam segurança
Testes como frequência de bits, runs, autocorrelação e baterias mais completas podem detectar vieses grosseiros, mas não provam que um gerador é criptograficamente seguro. Um gerador pode passar em muitos testes e ainda ser previsível se o atacante conseguir inferir o estado interno ou se a semente for fraca.
Quando testes fazem sentido
Validação de integração: garantir que você não está acidentalmente usando um PRNG determinístico sem seed adequada.
Detecção de regressões: mudanças de ambiente (VM, container, hardware) podem reduzir entropia; testes podem sinalizar padrões inesperados.
Monitoramento de TRNG: em hardware, testes online podem detectar falhas (sensor travado, ruído ausente).
Como testar de forma útil (passo a passo)
Passo 1: defina o que você está testando
Você está testando a saída do CSPRNG do SO? Em geral, você confia nele e testa apenas para detectar uso incorreto.
Você está testando um TRNG/ruído físico? Aí sim faz sentido uma bateria estatística e testes de saúde (health tests).
Passo 2: colete amostras corretamente
Coleta grande o suficiente para o teste pretendido (ordem de megabytes, dependendo do teste).
Evite misturar fontes diferentes na mesma amostra sem controle (ex.: parte vem de um fallback).
Registre condições do ambiente: carga do sistema, tipo de VM, momento do boot, disponibilidade de hardware RNG.
Passo 3: rode testes e interprete como “sinal”, não como “prova”
Se um teste falhar, isso é um alerta forte. Se passar, isso apenas reduz a chance de vieses simples. A decisão de segurança deve se basear principalmente em: uso de APIs corretas, desenho do sistema, e garantias do componente (SO/biblioteca/hardware), não em “passou no teste”.
Falhas comuns e como evitá-las
1) Usar PRNG não criptográfico
Geradores como os usados para simulação, jogos ou embaralhamento podem ser determinísticos e previsíveis. Se um atacante consegue inferir o estado (às vezes com poucas saídas observadas), ele prevê tokens e chaves derivadas. Regra prática: para qualquer material de segurança, use apenas CSPRNG do SO ou bibliotecas criptográficas que delegam ao SO.
2) Seed fraca (tempo, PID, MAC, contador)
Sem entropia real, um PRNG vira um gerador de “padrões complexos”, mas ainda adivinháveis. Seeds baseadas em timestamp podem ser buscadas em uma janela pequena. Em ambientes com relógio sincronizado, a janela é ainda menor.
// Anti-exemplo (pseudocódigo):
seed = current_time_millis()
prng.seed(seed)
secret = prng.next_bytes(32)
// Um atacante pode testar seeds possíveis em torno do horário observado.3) Reutilização de nonce/IV por erro de implementação
Mesmo quando a chave é forte, repetir um nonce/IV em certos esquemas pode vazar informação ou permitir forja. Causas típicas: contador reiniciado após reboot, estado não persistido, concorrência gerando colisões, ou truncamento do nonce para “caber” em um campo.
Mitigação prática:
Se o esquema permitir nonce determinístico (por exemplo, contador), garanta persistência e monotonicidade, e trate rollback como incidente.
Se o esquema exigir aleatoriedade, gere nonces com CSPRNG e use tamanho completo recomendado.
Em sistemas distribuídos, evite gerar nonces “locais” sem coordenação quando a unicidade global é necessária.
4) Baixa entropia no boot e clonagem de imagens
Instâncias clonadas podem iniciar com estado semelhante se o sistema não tiver entropia suficiente no início. Isso pode resultar em chaves/tokens repetidos entre máquinas. Mitigações:
Garanta que a plataforma fornece entropia no boot (mecanismos de seed persistente do SO, hardware RNG, ou serviço de entropia da infraestrutura).
Evite gerar chaves de longo prazo no primeiro segundo de vida da instância sem garantir que o CSPRNG está pronto.
Se você constrói imagens, evite “pré-gerar” material secreto durante o build e depois clonar para produção.
5) Truncamento e redução involuntária de entropia
Exemplos: gerar 32 bytes e depois usar apenas 8 “porque é suficiente”; ou converter para número decimal e cortar dígitos; ou aplicar mod (%) em um intervalo não potência de 2, introduzindo viés. Mitigação:
Defina explicitamente o alvo de entropia (ex.: 128 bits para tokens) e preserve esse tamanho até o uso.
Para sortear em intervalos arbitrários, use técnicas sem viés (rejection sampling) em vez de módulo simples.
6) Confundir “aleatório” com “secreto”
Alguns valores podem ser públicos e ainda assim precisam ser aleatórios/únicos (ex.: certos nonces). Outros precisam ser secretos (chaves, seeds). Tratar nonce como segredo pode levar a decisões erradas (como armazenar em local “seguro” e acabar reutilizando), e tratar segredo como “apenas aleatório” pode levar a vazamento em logs.
7) Re-semeadura e estado comprometido
Se o estado interno de um CSPRNG for exposto (por bug, dump de memória, leitura indevida), um bom desenho deve permitir recuperação após coletar nova entropia (reseeding). Na prática, você reduz risco ao:
Preferir APIs do SO que já implementam reseeding e isolamento.
Minimizar tempo de vida de processos que mantêm muito estado sensível.
Evitar exportar/serializar estados de PRNG.
Dimensionamento prático: quanta entropia eu preciso?
Tokens e identificadores de sessão
Para tokens de autenticação que um atacante pode tentar adivinhar, um alvo comum é pelo menos 128 bits de entropia efetiva. Isso permite margem contra tentativas online e vazamentos parciais. Em ambientes de alta criticidade ou longa validade, pode-se aumentar.
Chaves e seeds
Chaves devem seguir o tamanho recomendado pelo algoritmo e pelo nível de segurança. Seeds para CSPRNG devem ter entropia suficiente para impedir busca exaustiva. O ponto central: não “invente” seed; obtenha do CSPRNG do SO.
Nonces/IVs
O tamanho e o requisito (unicidade vs imprevisibilidade) dependem do esquema. Se a exigência for unicidade, o risco principal é colisão/repetição. Se a exigência for imprevisibilidade, o risco é o atacante antecipar o valor e explorar isso. Em ambos os casos, o caminho seguro é seguir a especificação do mecanismo e usar geração robusta.
Checklist operacional para evitar incidentes de aleatoriedade
Use exclusivamente CSPRNG do sistema operacional para qualquer valor de segurança (chaves, tokens, nonces aleatórios).
Não implemente PRNG próprio e não faça “seed manual” com tempo/contador.
Garanta que o ambiente (VM/container) fornece entropia suficiente no boot; evite gerar segredos críticos antes do CSPRNG estar pronto.
Defina requisitos por tipo de valor: secreto vs público; único vs imprevisível; tamanho mínimo de entropia.
Evite truncar, aplicar módulo com viés, ou converter para formatos que reduzam entropia.
Não registre valores aleatórios sensíveis; trate logs como superfície de ataque.
Se usar hardware RNG/TRNG, implemente monitoramento e testes de saúde; trate falhas como incidentes.
Teste para detectar uso incorreto (ex.: repetição de tokens, padrões em nonces), mas não use testes estatísticos como prova de segurança.