Erros comuns de criptografia
Usar criptografia não garante segurança. Implementações incorretas criam uma falsa sensação de proteção enquanto deixam dados expostos. Estes são os erros mais comuns.
Erro 1: modo ECB (Electronic Codebook)
No modo ECB, cada bloco de dados é cifrado independentemente com a mesma chave. Blocos iguais geram blocos cifrados iguais.
Dado: [BLOCO_A][BLOCO_A][BLOCO_B]
ECB: [CIFRA_A][CIFRA_A][CIFRA_B]
^--- padrão visível ---^
Isso vaza estrutura do dado original. O exemplo clássico: cifrar uma imagem bitmap com AES-ECB — a silhueta permanece visível.
Solução: use CBC com IV aleatório, ou melhor, AES-GCM.
from Crypto.Cipher import AES
# Errado
cipher = AES.new(key, AES.MODE_ECB)
# Correto
import os
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
Erro 2: IV reutilizado
CBC e CTR requerem um IV (vetor de inicialização) único por mensagem. Reutilizar o mesmo IV com a mesma chave quebra a confidencialidade.
Em modo CTR, dois textos cifrados com mesmo IV e chave permitem XOR entre eles, revelando os dados.
C1 = M1 ⊕ keystream
C2 = M2 ⊕ keystream (mesmo IV → mesmo keystream)
C1 ⊕ C2 = M1 ⊕ M2 ← estrutura das mensagens fica exposta
Solução: gere IV aleatório com os.urandom(16) a cada cifração. Armazene o IV junto ao ciphertext (ele não precisa ser secreto).
Erro 3: chave hardcoded
# Jamais faça isso
KEY = b"minha_chave_fixa_1234567890abcdef"
def cifrar(dado):
cipher = AES.new(KEY, AES.MODE_GCM)
return cipher.encrypt(dado)
A chave no código-fonte vaza via repositório git, logs, binários descompilados. Uma chave comprometida compromete todos os dados históricos.
Solução: carregue a chave de variável de ambiente ou de um serviço de segredos.
import os
KEY = os.environ["APP_ENCRYPTION_KEY"].encode()
# Ou use AWS Secrets Manager, HashiCorp Vault, etc.
Erro 4: cifrar sem autenticar
AES-CBC cifra, mas não garante integridade. Um atacante pode alterar o ciphertext e a decifração vai produzir lixo ou, pior, um valor controlado (bit-flipping attack).
Cifrado original: [...][TARGET_BLOCO][...]
Atacante inverte bit no bloco anterior → altera TARGET_BLOCO após decifração
Solução: use modos autenticados — AES-GCM ou AES-CCM. Eles combinam cifração + autenticação em uma operação.
from Crypto.Cipher import AES
import os
key = os.urandom(32)
nonce = os.urandom(16)
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
ciphertext, tag = cipher.encrypt_and_digest(b"dado sensivel")
# tag verifica integridade na decifração
Erro 5: número aleatório fraco
Não use random do Python ou rand() do C para gerar chaves ou IVs. Esses geradores são pseudoaleatórios e não são seguros criptograficamente.
# Errado
import random
key = random.randbytes(32)
# Correto
import os
key = os.urandom(32)
Resumo dos erros
| Erro | Consequência | Fix |
|---|---|---|
| Modo ECB | Vaza padrões | Use GCM ou CBC com IV |
| IV reutilizado | Quebra confidencialidade | IV aleatório por mensagem |
| Chave hardcoded | Exposição via código | Variável de ambiente/vault |
| Sem autenticação | Bit-flipping attack | Use AES-GCM |
| PRNG fraco | Chave previsível | Use os.urandom() |