Acha que implementar nonces é simples? Pense novamente. Quer esteja a construir protocolos onchain ou infraestrutura offchain, a implementação adequada de nonces é uma das partes mais complicadas da segurança criptográfica. Vamos mergulhar em porque a proteção contra replay é mais difícil do que parece 👇
2/ Primeiro, vamos entender as assinaturas digitais. Na criptografia de chave pública (como BLS), você tem uma chave privada que assina mensagens e uma chave pública que as verifica. No Ethereum: endereço = hash da chave pública mensagem = hash da transação assinatura = 64 bytes de prova criptográfica
3/ Aqui está o problema: a matemática na maioria dos protocolos de criptografia de chave pública não limita quantas vezes uma assinatura pode ser verificada em relação à mesma mensagem. Uma vez que você tem uma assinatura válida, pode reproduzi-la infinitamente. Isso abre a porta para ataques de reprodução.
4/ Insira o nonce: um "número usado uma vez" que previne ataques de repetição. Quando um consumidor recebe uma mensagem com um nonce, ele verifica se esse nonce foi usado antes. Se sim → rejeitar. As transações Ethereum usam este padrão.
5/ Mas a implementação de nonces é enganosamente complexa. Requisitos chave: - Os nonces NUNCA devem ser reutilizáveis (nesta cadeia ou em outras) - Devem prevenir ataques de repetição permanentemente - Necessitam de mecanismos para lidar com o crescimento do armazenamento - Devem ser resistentes a ataques de front-running
6/ A solução ingênua: armazenar todos os nonces em um banco de dados para sempre. Isso tem dois grandes problemas: a) Crescimento de armazenamento sem limites (especialmente com ataques de spam) b) Vulnerabilidade a ataques de front-running O problema (a) é mais fácil de resolver do que (b). Vamos abordar o armazenamento primeiro...
7/ Nonces baseados em timestamp resolvem o crescimento do armazenamento! Use timestamp + período de expiração. Nonces com mais de 5 minutos são deletados da base de dados. Mas e quanto a mensagens simultâneas da mesma conta? Elas compartilham um timestamp. Solução: timestamp + random_bytes para unicidade granular.
8/ O front-running é a parte complicada. Atores maliciosos podem interceptar assinaturas válidas, fazer front-running delas para marcar nonces como usadas, e então a chamada do usuário legítimo é rejeitada. Isso é problemático na cadeia com operações em lote se uma assinatura ruim rejeitar todo o lote. Para offchain: use criptografia TLS! Não deixe que nenhum ator malicioso veja a nonce ou a assinatura.
9/ Não se esqueça da persistência! Se o seu cache de nonce estiver apenas na memória, os atacantes podem reproduzir nonces antigos após reinicializações do sistema. Sempre persista o estado do nonce em armazenamento durável e recarregue na inicialização. Caches apenas na memória = janela de vulnerabilidade de reprodução.
10/ Nonces únicos por consumidor! Ao transmitir para vários utilizadores, cada um deve receber uma mensagem/sinal diferente. Caso contrário, você está vulnerável a ataques Man-in-the-Middle, onde um receptor reencaminha a mensagem, impersonando o remetente original.
11/ Nonces incrementais (como no Ethereum, nonce = nonce anterior + 1) têm o seu lugar, mas cuidado! Eles criam enormes desafios para a infraestrutura offchain: mensagens fora de ordem, problemas de sincronização e cenários de recuperação complexos. Use apenas se tiver confiança de que as mensagens irão (ou devem) chegar em sequência.
Resumo - Lista de verificação da implementação de nonces: ✅ Use nonces para prevenir ataques de repetição ✅ Persistir o estado do nonce entre reinicializações ✅ Implementar mecanismos de expiração (timestamp + limpeza) ✅ Tornar os nonces únicos por receptor ✅ Proteger contra front-running com canais encriptados ✅ Evitar nonces incrementais a menos que a ordem esteja garantida A segurança está nos detalhes! 🛡️
1,37K