◇ OpenCyber Academy
Graduação · Capítulo 3 · Português

Capítulo 3 — 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.

Capítulo 3 — Programação I

Mapa da aula

Aula 03 publicada. Mapa, exemplo, EX005.

flowchart TD
  N0["3.1 Programas como enunciados precisos"]
  N1["3.2 Texto versus bytes"]
  N2["3.3 Aleatoriedade e hashing na biblioteca padrão"]
  N3["3.5 Atividade prática"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX005"]

Desenho lógico

flowchart LR
  N0["3.1 Programas como enunciados precisos"]
  N1["3.2 Texto versus bytes"]
  N2["3.3 Aleatoriedade e hashing na biblioteca padrão"]
  N3["3.5 Atividade prática"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX005"]
[3.1 Programas como enunciados precisos]
    |
    v
[3.2 Texto versus bytes]
    |
    v
[3.3 Aleatoriedade e hashing na biblioteca padrão]
    |
    v
[3.5 Atividade prática]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX005]

Objetivos de aprendizagem

Você vai (1) escrever pequenos programas em Python com funções, laços e condicionais; (2) tratar corretamente texto e bytes; (3) usar os módulos hashlib e secrets da biblioteca padrão; e (4) testar uma função com asserções.

3.1 Programas como enunciados precisos

Um programa é um argumento que uma máquina consegue conferir executando-o. O trabalho de segurança usa programas para reproduzir afirmações: se um relatório diz que "esta configuração oferece apenas troca de chaves clássica", um script curto que interpreta a configuração e imprime os grupos torna a afirmação repetível. Ao longo deste livro, os laboratórios são programas curtos em Python que usam apenas a biblioteca padrão, para que todo leitor possa executá-los offline e comparar a saída.

Comece pelas construções básicas: as variáveis guardam valores; as funções dão nome a um cálculo reutilizável; os laços for repetem; os comandos if escolhem. Programas legíveis usam nomes descritivos, funções pequenas e comentários que explicam por quê, e não o quê.

3.2 Texto versus bytes

As funções criptográficas operam sobre bytes, não sobre texto. Em Python, "abc" é texto (uma sequência de caracteres Unicode) e b"abc" são bytes. Converter texto em bytes exige uma codificação, normalmente UTF-8: "abc".encode("utf-8"). Um bug clássico é calcular o hash de str(b"abc"), que é o texto de seis caracteres b'abc', e não os três bytes. O resumo fica errado em silêncio, e dois sistemas que discordam quanto à codificação não conseguirão verificar as assinaturas um do outro. Os problemas de interoperabilidade nas implantações pós-quânticas costumam ser desse tipo: ordem de bytes errada, codificação errada, comprimento errado.

3.3 Aleatoriedade e hashing na biblioteca padrão

secrets.token_bytes(32) devolve 32 bytes do gerador criptograficamente seguro do sistema operacional; o módulo random não é adequado para chaves, porque a sua saída é previsível a partir da semente. hashlib.sha256(data).hexdigest() calcula um resumo SHA-256; hashlib.sha3_256 e hashlib.shake_128 calculam membros da família SHA-3 usados dentro do ML-KEM e do ML-DSA. Para comparar valores secretos, use hmac.compare_digest, que leva um tempo independente de onde as entradas diferem.

Os testes de resposta conhecida usam entradas e saídas publicadas, então uma implementação errada falha de imediato. A família SHA-3 é útil neste livro porque o ML-KEM e o ML-DSA a usam internamente. Nunca imprima bytes secretos durante a depuração; imprima o seu comprimento ou um resumo.

3.4 Exemplo resolvido

Um estagiário da HCU escreve uma função para calcular a impressão digital de certificados:

import hashlib
def fingerprint(der: bytes) -> str:
    return hashlib.sha256(der).hexdigest()
assert fingerprint(b"") == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
print("fingerprint test passed")

A asserção usa como resposta conhecida o resumo publicado da cadeia vazia. Se alguém depois mudar a função para calcular o hash de texto, o teste falha imediatamente.

O teste confere a função contra um fato externo, e não contra a sua própria saída, o que é o que lhe permite falhar. Um segundo teste, com os bytes de um certificado real e a sua impressão digital publicada, detectaria um erro diferente, como calcular o hash de uma codificação em texto do certificado em vez dos seus bytes brutos. O estagiário acrescenta os dois testes ao repositório da HCU, para que cada mudança posterior seja conferida automaticamente.

3.5 Atividade prática

Escreva is_valid_length(alg, data), que devolve True apenas se data tiver o comprimento esperado para aquele algoritmo, usando um dicionário como {"ML-KEM-768-ek": 1184} (o tamanho da chave de encapsulamento na FIPS 203). Teste uma entrada correta e duas incorretas.

Uma verificação de comprimento não é uma verificação de segurança; ela só detecta erros grosseiros, como valores truncados ou concatenados. Ainda assim vale a pena tê-la, porque muitos bugs de integração nas migrações pós-quânticas vêm de buffers dimensionados para chaves clássicas. Tire os tamanhos esperados da própria norma, e não de um post de blog, e anote o documento e a tabela que você usou, para que um revisor possa conferir cada número.

3.6 Erros comuns e limites

Cada erro produz um código que parece funcionar. Uma chave do módulo random parece aleatória, mas pode ser prevista por qualquer um que descubra a semente. O resumo dos bytes errados parece um resumo e só falha quando comparado com outro sistema. Um teste que compara um valor com ele mesmo sempre passa, então dá uma falsa confiança. Registrar segredos nos logs os deixa em arquivos que mais pessoas podem ler do que o próprio programa.

Exercícios

Síntese

Programas pequenos e testados tornam as afirmações de segurança reproduzíveis. Os bytes, as codificações e a aleatoriedade segura são onde o código criptográfico dos iniciantes mais costuma errar.

Continue estudando — capítulo 03 de 40

← Capítulo 02 · Índice de capítulos do curso · Capítulo 04 →

Siga para a próxima lição escrita.