Otimizando a Verificação de Integridade de Mensagens com FNV-1a em Go
Vimos no artigo HMAC (Hash-based Message Authentication Code) como essa técnica garante que a mensagem não foi alterada durante o transporte e confirma a validade da assinatura.
No entanto, esse processo, embora seguro, é lento e consome muitos recursos. Quando precisamos apenas verificar a integridade da mensagem sem validar uma assinatura, podemos usar uma função de hash mais rápida. Para isso, utilizaremos o algoritmo FNV-1a (Fowler-Noll-Vo), conhecido por sua rapidez e baixa taxa de colisão.
Primeiro, vamos criar um pool de hashes para evitar a alocação de memória a cada chamada da função de hash. Isso reduz a pressão sobre o garbage collector.
var (
hashPool = sync.Pool{
New: func() interface{} {
return fnv.New32a()
},
}
)
Para gerenciar o pool de hashes, criaremos duas funções: uma para obter um hash do pool e outra para devolvê-lo.
func getHash() hash.Hash32 {
return hashPool.Get().(hash.Hash32)
}
func putHash(h hash.Hash32) {
hashPool.Put(h)
}
Agora, vamos criar uma função para calcular o checksum da mensagem. Essa função obtém um hash do pool, calcula o checksum e devolve o hash para o pool.
func checksum(data []byte) uint32 {
hash := getHash()
defer putHash(hash)
hash.Reset()
_, _ = hash.Write(data)
return hash.Sum32()
}
A partir de agora, podemos usar a função checksum
para calcular o hash da mensagem. Esse sistema é muito mais rápido que o HMAC e ideal para sistemas como um broker de mensagens, que precisa transmitir um grande fluxo de informações.
Esse sistema não verifica a autenticidade da mensagem, apenas sua integridade. Contudo, em muitos casos, isso é suficiente. A segurança pode ser garantida por outros meios, como uma conexão segura TLS.
Vídeo com a explicação do código: