OpenCyber Academy
Engenharia · Capítulo 4 · Português
Código do curso: OCA-123Capítulo 04: OCA-123-C004

Capítulo 4 — Programação I

Ensino gratuito e aberto para quem deseja proteger pessoas e tecnologias. Não é preciso criar uma conta para estudar ou consultar as respostas.

Mapa da aula

Aula 04 publicada. Mapa, exemplo, EX010.

flowchart TD
  N0["4.1 Bytes não são texto"]
  N1["4.2 Usar o hashlib"]
  N2["4.3 Formatos canônicos"]
  N3["Síntese"]
  N0 --> N1 --> N2 --> N3
  N3 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX010"]

Desenho lógico

flowchart LR
  N0["4.1 Bytes não são texto"]
  N1["4.2 Usar o hashlib"]
  N2["4.3 Formatos canônicos"]
  N3["Síntese"]
  N0 --> N1 --> N2 --> N3 --> Q["EX010"]
[4.1 Bytes não são texto]
    |
    v
[4.2 Usar o hashlib]
    |
    v
[4.3 Formatos canônicos]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX010]

Objetivos de aprendizagem

Você vai (1) representar corretamente bytes, texto e hexadecimal; (2) usar as funções de hash da biblioteca padrão; (3) evitar erros comuns de codificação que quebram verificações criptográficas.

4.1 Bytes não são texto

As funções criptográficas operam sobre bytes, e não sobre caracteres. Em Python, "litres" é texto e b"litres" são bytes; converter entre os dois exige uma codificação explícita, como UTF-8. O primeiro bug de Aiyana vem de calcular o hash de uma leitura num sistema com uma codificação diferente da de outro, de modo que leituras iguais produziram digests diferentes. Ela aprende a fixar uma codificação canônica na especificação, a converter uma única vez na fronteira e a manter bytes em todo o interior. O hexadecimal é um formato de exibição de bytes: dois caracteres hexadecimais representam um byte, e é por isso que um digest SHA-256 de 32 bytes é impresso com 64 caracteres.

4.2 Usar o hashlib

O módulo hashlib oferece o SHA-256 e outras funções do FIPS 180-4. Um hash leva uma entrada de qualquer tamanho a um digest de tamanho fixo; mudar um bit muda cerca de metade dos bits da saída. Aiyana escreve pequenas funções que calculam o hash de uma string de leitura e imprimem o digest hexadecimal e depois confere vetores de teste publicados na norma para confirmar que está chamando a função corretamente. Ela aprende a diferença entre chamar update repetidamente num objeto de hash, o que calcula o hash da concatenação, e calcular o hash de cada pedaço separadamente, o que dá resultados diferentes que confundiram seu primeiro teste.

4.3 Formatos canônicos

Dois programas precisam concordar byte a byte antes que hashes ou assinaturas possam coincidir. Aiyana define um formato canônico de leitura para a Ridgeway: ordem fixa dos campos, separadores de ponto e vírgula, litros inteiros e timestamps em UTC com um Z no final. Ela evita litros em ponto flutuante, porque 18342.0 e 18342 teriam hashes diferentes. Ela também evita que a ordem de impressão de um dicionário defina os bytes. Essa disciplina antecipa os capítulos seguintes, em que as leituras são autenticadas com HMAC e o firmware com assinaturas; ambos falham, sem causar dano, mas de modo confuso, se o emissor e o receptor discordarem sobre os bytes exatos.

Exemplo resolvido

Aiyana corrige um teste que falhava codificando as leituras em UTF-8 uma única vez, usando litros inteiros e timestamps em UTC, e depois confirma suas chamadas ao SHA-256 contra um vetor de teste do FIPS 180-4.

Caso sintético. O formato de leitura foi inventado para a Ridgeway; o FIPS 180-4 é real.

Erros e limites

Hash não é cifração: qualquer pessoa pode calcular um digest. Misturar texto e bytes muda os resultados silenciosamente, então especifique as codificações explicitamente.

Exercícios

Síntese

A programação criptográfica correta começa com bytes, codificações explícitas, vetores de teste verificados e um formato canônico com que os dois lados concordam.

Respostas comentadas

EX010. O digest tem 32 bytes, e cada byte é escrito como dois caracteres hexadecimais.

EX011. Os dois sistemas codificaram o mesmo texto de leitura com codificações diferentes, então os bytes do hash eram diferentes.

EX012. Representações em ponto flutuante como 18342.0 e 18342 são sequências de bytes diferentes e nunca teriam o mesmo hash nem passariam na mesma verificação.