Mapa da aula
Aula 28 publicada. Mapa, exemplo, EX082.
flowchart TD
N0["28.1 Cadeias de hashes"]
N1["28.2 Forma canônica"]
N2["Laboratório — custódia à prova de adulteração"]
N3["28.3 Lendo o resultado"]
N4["28.4 Ancoragem"]
N5["28.5 Correções"]
N6["28.6 Desempenho"]
N7["28.7 Testes"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX082"]
Desenho lógico
flowchart LR
N0["28.1 Cadeias de hashes"]
N1["28.2 Forma canônica"]
N2["Laboratório — custódia à prova de adulteração"]
N3["28.3 Lendo o resultado"]
N4["28.4 Ancoragem"]
N5["28.5 Correções"]
N6["28.6 Desempenho"]
N7["28.7 Testes"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX082"]
[28.1 Cadeias de hashes]
|
v
[28.2 Forma canônica]
|
v
[Laboratório — custódia à prova de adulteração]
|
v
[28.3 Lendo o resultado]
|
v
[28.4 Ancoragem]
|
v
[28.5 Correções]
|
v
[28.6 Desempenho]
|
v
[28.7 Testes]
|
v
[Exemplo resolvido] --> [Exercício EX082]
Objetivos de aprendizagem
Você vai (1) implementar um log de custódia encadeado por hashes; (2) detectar uma entrada editada; (3) explicar por que os elos posteriores se quebram; (4) decidir como as correções são registradas.
28.1 Cadeias de hashes
O valor do elo de cada entrada de custódia é o hash do elo anterior mais o conteúdo da entrada. Alterar qualquer entrada altera seu elo e todos os elos posteriores, então a edição do histórico pode ser detectada recalculando a cadeia. Escrito como fórmula, elo_n = H(elo_{n−1} ‖ entrada_n), em que o primeiro elo usa um valor inicial fixo. Um verificador só precisa das entradas e da função de hash para recalcular todos os elos e compará-los com os valores armazenados. Como cada elo depende de todas as entradas anteriores, o valor do último elo funciona como uma impressão digital de todo o histórico até aquele ponto.
28.2 Forma canônica
As entradas são serializadas com as chaves ordenadas, para que o mesmo conteúdo sempre produza os mesmos bytes; do contrário, uma reordenação inofensiva quebraria a cadeia. O JSON permite escrever o mesmo objeto de muitas maneiras: a ordem das chaves, o espaçamento, os formatos de número e os caracteres escapados podem variar. Priya fixa as regras: chaves ordenadas, nenhum espaço em branco extra, codificação UTF-8 e horários sempre escritos como strings ISO. Um teste serializa a mesma entrada construída em duas ordens diferentes e confere que os bytes, e portanto os hashes, são idênticos.
Laboratório — custódia à prova de adulteração
"""Hash-chained chain-of-custody log; detect an edited entry."""
import hashlib, json
def chain(entries):
prev, out = "0"*64, []
for e in entries:
prev = hashlib.sha256((prev + json.dumps(e, sort_keys=True)).encode()).hexdigest()
out.append(prev)
return out
log = [{"item": "EV-7", "who": "Officer A", "act": "seized"},
{"item": "EV-7", "who": "Clerk B", "act": "received"},
{"item": "EV-7", "who": "Examiner C", "act": "imaged"}]
sealed = chain(log)
log[1]["who"] = "Clerk Z"
now = chain(log)
bad = [i for i, (a, b) in enumerate(zip(sealed, now)) if a != b]
print("entries:", len(log), "first broken link:", bad[0] if bad else None, "links affected:", len(bad))
Execute com python3 lab_custody.py. Saída verificada:
entries: 3 first broken link: 1 links affected: 2
28.3 Lendo o resultado
Três entradas são seladas. Quando a entrada 1 (o recebimento pelo escrevente) é alterada de "Clerk B" para "Clerk Z", o recálculo mostra o primeiro elo quebrado no índice 1 e 2 elos afetados: essa entrada e a seguinte. A entrada 0 continua sendo verificada, o que diz ao revisor onde o histórico divergiu. Apontar o primeiro elo quebrado importa na prática. O revisor sabe que as entradas antes do índice 1 estão intactas e que a alteração aconteceu no recebimento pelo escrevente ou depois dele. Combinando isso com backups ou com valores ancorados, ele pode então descobrir o que a entrada dizia originalmente. O exercício também mostra que uma entrada posterior se quebra mesmo que seu próprio conteúdo não tenha mudado.
28.4 Ancoragem
Uma cadeia, sozinha, pode ser reconstruída por inteiro por alguém com acesso de gravação. Imprimir ou armazenar externamente, de tempos em tempos, o valor do último elo (ancoragem) impede a reconstrução silenciosa: uma cadeia reconstruída não vai corresponder ao valor ancorado. Em Northfield, o relatório diário de monitoramento inclui o valor do último elo e é enviado por e-mail à gerente da qualidade, que fica fora da zona de exame, e impresso para um arquivo em papel. Reescrever o histórico significaria, portanto, alterar ao mesmo tempo o servidor, os relatórios enviados por e-mail e as cópias em papel. O verificador de Priya aceita um valor de âncora como entrada e relata se a cadeia atual ainda passa por ele.
28.5 Correções
Os erros são corrigidos por uma nova entrada que declara a correção e faz referência à original, mantendo a cadeia intacta. Uma entrada de correção nomeia a entrada que corrige pelo índice e pelo valor do elo, declara o campo corrigido e seu novo valor, e informa um motivo e o aprovador. As telas mostram o valor corrigido com um marcador, e um clique mostra o original. Como nada é sobrescrito, a cadeia continua válida, e o registro mostra tanto o erro quanto a forma como foi corrigido.
28.6 Desempenho
Calcular o hash de entradas pequenas é rápido; a cadeia é verificada em milissegundos mesmo com milhares de entradas. Priya mede: verificar uma cadeia sintética de 100.000 entradas leva menos de um segundo na estação de trabalho mais antiga do laboratório. Isso significa que a cadeia inteira pode ser conferida a cada inicialização do servidor, e não apenas na rotina noturna. O número é registrado nas notas de desempenho com os detalhes do hardware, para que uma lentidão posterior seja notada e investigada. O tempo de verificação cresce linearmente com o número de entradas.
28.7 Testes
Os testes cobrem uma cadeia intacta, uma entrada editada, uma entrada apagada e um par reordenado. Cada teste declara qual elo deve falhar primeiro. Editar a entrada 5 deve falhar em 5. Apagar a entrada 5 deve falhar na entrada que passa a ocupar o índice 5, porque seu valor armazenado do elo anterior já não corresponde. Trocar as entradas 5 e 6 deve falhar em 5. Outro teste, com uma cadeia vazia, confirma que o verificador relata "nenhuma entrada" em vez de uma falsa aprovação. Um último teste altera apenas o valor armazenado do elo, não a entrada, e espera que o verificador o detecte.
Exemplo resolvido
Priya ancora o valor do último elo todos os dias no log assinado da gerente da qualidade. Ao testar um ataque de reconstrução completa num cenário sintético, a cadeia reconstruída é verificada internamente, mas seu valor final difere da âncora, e assim a reconstrução é detectada.
Caso sintético. As entradas vêm do script do laboratório.
Erros e limites
Uma cadeia detecta alterações; não as impede nem diz quem as fez — isso cabe aos logs de acesso.
Exercícios
- EX082 — Resultado do laboratório. Relate o primeiro elo quebrado e os elos afetados.
Mostrar critérios de avaliação
Rubrica: 3 = índice 1, 2 elos, com explicação; 2 = só os números; 1 = errado; 0 = nada. - EX083 — Ancoragem. Por que ancorar externamente o último elo?
Mostrar critérios de avaliação
Rubrica: 3 = impede a reconstrução completa não detectada; 2 = parcial; 1 = backup; 0 = nada. - EX084 — Chaves ordenadas. Por que serializar com as chaves ordenadas?
Mostrar critérios de avaliação
Rubrica: 3 = bytes canônicos, para a cadeia ficar estável; 2 = parcial; 1 = legibilidade; 0 = nada.
Síntese
Cadeias de hashes com forma canônica e âncoras externas tornam o histórico de custódia à prova de adulteração.
Continue estudando — capítulo 28 de 50
← Capítulo 27 (rascunho) · Índice de capítulos do curso · Capítulo 29 (rascunho) →