Capítulo 14 — Criptografia e serviços de confiança: métodos I
Mapa da aula
Aula 14 publicada. Mapa, exemplo, EX040.
flowchart TD
N0["14.1 Webhooks assinados"]
N1["Laboratório — Verificação de webhooks"]
N2["14.2 Ler a execução do webhook"]
N3["14.3 Combinar as verificações"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX040"]
Desenho lógico
flowchart LR
N0["14.1 Webhooks assinados"]
N1["Laboratório — Verificação de webhooks"]
N2["14.2 Ler a execução do webhook"]
N3["14.3 Combinar as verificações"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX040"]
[14.1 Webhooks assinados]
|
v
[Laboratório — Verificação de webhooks]
|
v
[14.2 Ler a execução do webhook]
|
v
[14.3 Combinar as verificações]
|
v
[Síntese]
|
v
[Exemplo resolvido] --> [Exercício EX040]
Objetivos de aprendizagem
Você vai (1) verificar webhooks assinados com HMAC; (2) limitar a repetição com carimbos de tempo; (3) combinar as verificações corretamente no código.
14.1 Webhooks assinados
O provedor de pagamentos avisa a prefeitura quando uma licença é paga enviando uma requisição HTTP com um corpo JSON, um cabeçalho de carimbo de tempo e um cabeçalho de assinatura. A assinatura é um HMAC-SHA256, como na RFC 2104, calculado sobre o carimbo de tempo e o corpo com um segredo compartilhado entre o provedor e a prefeitura. A prefeitura recalcula o HMAC e compara. Rosa aprende que a comparação precisa usar uma função de tempo constante, hmac.compare_digest no Python, para que os atacantes não consigam descobrir a assinatura correta byte a byte a partir do tempo de resposta.
Laboratório — Verificação de webhooks
"""Verify a signed webhook with HMAC-SHA256 plus a 300-second timestamp window (synthetic payment notice)."""
import hmac, hashlib
SECRET = b"demo-webhook-secret-not-for-production"
WINDOW = 300
def sign(ts, body): return hmac.new(SECRET, f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
def verify(ts, body, sig, now):
return abs(now - ts) <= WINDOW and hmac.compare_digest(sig, sign(ts, body))
def main():
body, ts = b'{"permit":"PK-2291","paid":45.00}', 1767225600
sig = sign(ts, body)
print("fresh, intact:", verify(ts, body, sig, now=ts + 20))
print("amount edited:", verify(ts, body.replace(b"45.00", b"4.50"), sig, now=ts + 20))
print("replayed after 1 hour:", verify(ts, body, sig, now=ts + 3600))
if __name__ == "__main__":
main()
Execute com python3 lab_webhook.py. Saída verificada:
fresh, intact: True
amount edited: False
replayed after 1 hour: False
14.2 Ler a execução do webhook
Uma notificação nova e intacta é verificada como True. Quando o valor pago é editado de 45.00 para 4.50, a verificação falha, porque o HMAC deixa de coincidir. Quando a mesma notificação válida é repetida uma hora depois, a verificação falha, porque o carimbo de tempo fica fora da janela de 300 segundos. Rosa observa que a janela limita a repetição a cinco minutos, mas não a impede por completo; a prefeitura também registra os identificadores das notificações processadas e rejeita as duplicadas. O segredo de demonstração é fixo apenas para que a saída seja reproduzível; o segredo real fica no repositório de segredos.
14.3 Combinar as verificações
Rosa escreve a ordem das verificações: ler o corpo bruto exatamente como recebido, antes de qualquer análise do JSON que possa mudar os espaços; conferir a janela do carimbo de tempo; recalcular e comparar o HMAC; conferir que o identificador da notificação ainda não foi processado; e só então agir sobre o conteúdo. Ela também registra as falhas com os motivos para as operações, mas devolve um erro genérico a quem chamou. Owen revisa o código e pede que ela acrescente testes para cada caminho de falha, espelhando os casos do laboratório. Cada teste envia uma requisição montada e verifica tanto o código de resposta quanto a linha de log, para que nenhuma aceitação silenciosa passe despercebida.
Exemplo resolvido
Rosa verifica webhooks com HMAC e uma janela de 300 segundos, acrescenta verificações de identificadores duplicados e ordena as verificações para que os bytes brutos sejam verificados antes da análise.
Caso sintético. O segredo e a notificação são inventados; a RFC 2104 é real.
Erros e limites
Verificar depois de analisar o JSON pode falhar com mudanças inofensivas de formatação. Uma janela de carimbo de tempo sozinha não impede todas as repetições.
Exercícios
-
EX040 — Entrada da assinatura. O que o HMAC do provedor cobre? Rubrica: 3 = o carimbo de tempo e o corpo;; 2 = ambos;; 1 = só o corpo;; 0 = nenhuma.
-
EX041 — Resultados do laboratório. O que o laboratório imprimiu para as notificações editada e repetida? Rubrica: 3 = False para o valor editado e False para a repetição depois de uma hora;; 2 = ambos;; 1 = um;; 0 = nenhuma.
-
EX042 — Corpo bruto. Por que verificar o corpo bruto antes de analisar o JSON? Rubrica: 3 = a análise pode mudar bytes, como os espaços, quebrando a verificação;; 2 = bytes;; 1 = velocidade;; 0 = nenhuma.
Síntese
A segurança dos webhooks combina o HMAC sobre os bytes brutos, a comparação em tempo constante, uma janela de carimbo de tempo e a detecção de duplicatas.
Continue estudando — aula 14 (capítulo 14 de 30)
← Capítulo 13 · Índice das aulas · Capítulo 15 →
Continue para a próxima aula já escrita.