Criptografia
Criptografia, codificação e hash: diferenças explicadas
Separe codificação, criptografia e hash com laboratórios de Base64, SHA-256 e OpenSSL. Entenda por que Base64 não protege e o hash é de mão única.
Crie uma cifra de César em Python, teste com unittest e veja por que essa cifra não oferece confidencialidade real.
Você vai escrever uma função caesar(). Ela desloca letras do alfabeto inglês por um número de posições, deixa qualquer outro caractere como está e desfaz o deslocamento quando recebe um número negativo. Depois você roda um pequeno conjunto de testes e lê o que cada um verifica.
Você precisa apenas do Python 3. Se a ideia de cifra de deslocamento for nova, leia antes O que é a Cifra de César?.
Instale o Python 3 pelo python.org. O código usa só a biblioteca padrão, então não há nada para instalar com pip. Crie uma pasta para o laboratório e salve os arquivos nela.
A saída deste artigo veio do Python 3.12.10 no Windows 11. Não testei outras versões.
A função ord() do Python devolve o ponto de código Unicode de um caractere. chr() faz o caminho inverso e transforma um ponto de código de volta em caractere. Para a letra maiúscula A, o ponto de código é 65.
Execute no terminal:
python -I -c "print(ord('A'), chr(65))"Saída:
65 AA opção -I executa o Python em modo isolado. Variáveis de ambiente que começam com PYTHON são ignoradas, e a pasta atual não entra no caminho de busca de módulos. Use essa opção quando rodar código de uma pasta que você não escreveu.
O deslocamento trabalha com posições começando em zero. Subtrair 65 transforma A em 0 e Z em 25. O passo % 26 faz o resultado dar a volta no alfabeto, e somar 65 devolve a faixa de maiúsculas:
chr((ord(letter) - 65 + shift) % 26 + 65)As minúsculas começam em 97, então a mesma ideia usa 97 no lugar de 65.
O operador % do Python nunca devolve número negativo quando o divisor é positivo. É por isso que um deslocamento negativo funciona sem código extra:
python -I -c "print((0 - 3) % 26)"Saída:
23Zero menos três dá a volta e cai na posição 23, que é a letra X.
Salve este código como caesar_cipher.py. É o mesmo conteúdo do arquivo do laboratório.
"""Educational Caesar cipher only. NOT secure encryption.
Shift ASCII English A-Z/a-z; preserve every other Unicode character as-is.
"""
def caesar(text: str, shift: int) -> str:
shift %= 26
result = []
for character in text:
if 'A' <= character <= 'Z':
result.append(chr((ord(character) - 65 + shift) % 26 + 65))
elif 'a' <= character <= 'z':
result.append(chr((ord(character) - 97 + shift) % 26 + 97))
else:
result.append(character)
return ''.join(result)
if __name__ == '__main__':
print(caesar('HELLO, World!', 3)) # KHOOR, Zruog!
print(caesar('KHOOR, Zruog!', -3)) # HELLO, World!A primeira linha da função, shift %= 26, reduz qualquer deslocamento para a faixa de 0 a 25. Um deslocamento de 29 se comporta como um de 3, e um de -3 vira 23.
Execute o arquivo:
python -I caesar_cipher.pySaída:
KHOOR, Zruog!
HELLO, World!A função altera apenas as letras de A a Z e de a a z. Dígitos, espaços, pontuação e letras acentuadas passam sem mudança. Isso mantém o código curto. Uma cifra que tratasse letras acentuadas precisaria de uma regra para cada uma delas, e este laboratório não define nenhuma.
O laboratório também inclui test_caesar_cipher.py. Abra o terminal na pasta com os dois arquivos e execute:
python -I -m unittest discover -p 'test_*.py' -vSaída:
test_large_shift (test_caesar_cipher.CaesarCipherTest.test_large_shift) ... ok
test_lower (test_caesar_cipher.CaesarCipherTest.test_lower) ... ok
test_negative (test_caesar_cipher.CaesarCipherTest.test_negative) ... ok
test_roundtrip (test_caesar_cipher.CaesarCipherTest.test_roundtrip) ... ok
test_upper (test_caesar_cipher.CaesarCipherTest.test_upper) ... ok
test_wrap (test_caesar_cipher.CaesarCipherTest.test_wrap) ... ok
----------------------------------------------------------------------
Ran 6 tests in 0.001s
OKCada teste verifica um comportamento:
test_upper e test_lower confirmam que HELLO vira KHOOR e que attack vira dwwdfn.test_wrap confirma que Z avança para C. Isso só acontece se a volta no alfabeto estiver certa.test_large_shift confirma que um deslocamento de 29 dá o mesmo resultado que um de 3.test_negative testa a decifragem, deslocando DEF por -3.test_roundtrip cifra um texto com deslocamento 7, decifra com -7 e espera receber o original. O texto de exemplo tem pontuação, um dígito e o á, então também confere se os caracteres que não são letras passam intactos.Se você mudar o código e um teste falhar, a mensagem mostra a entrada, o valor esperado e o valor obtido. Leia essa mensagem antes de mudar mais alguma coisa.
A cifra de César tem apenas 25 deslocamentos úteis. O deslocamento 0 e o 26 devolvem o texto original. Uma pessoa consegue testar todos à mão, e um programa testa todos num instante.
A análise de frequência é um segundo problema. Em inglês, letras como E e T aparecem mais que Q ou Z. Em uma mensagem mais longa, as letras mais comuns do texto cifrado costumam apontar para as letras mais comuns do texto original.
Por isso, essa cifra não oferece confidencialidade real. Não a use para senhas, registros de clientes, tokens ou qualquer coisa que importe. Se você precisa de criptografia de verdade, use uma biblioteca bem testada e um algoritmo padrão. A OWASP Cryptographic Storage Cheat Sheet reúne as regras básicas para proteger dados armazenados.
Use este exercício para aprender aritmética modular, códigos de caracteres e a diferença entre uma transformação de brincadeira e uma cifra de verdade.
Depois que os testes passarem, você pode pedir a um modelo de linguagem que explique a linha com módulo, sugira casos de borda ou escreva mais testes. Um bom pedido já deixa claros os limites:
Revise esta cifra de César educacional. O que acontece com deslocamentos negativos, letras acentuadas e textos fora do alfabeto latino? Não a descreva como criptografia segura.
Rode qualquer teste que o modelo propuser antes de aceitá-lo. Modelos erram, e um teste que falha diz mais do que uma explicação confiante.
Quando o laboratório funcionar, guarde a pasta em um sistema de controle de versão para acompanhar as mudanças. O próximo artigo, O que é o GitHub?, explica como fazer isso.
Criptografia
Separe codificação, criptografia e hash com laboratórios de Base64, SHA-256 e OpenSSL. Entenda por que Base64 não protege e o hash é de mão única.
Criptografia
Por que hashes rápidos falham em senhas, o que fazem o salt e o fator de trabalho, e como gerar e verificar hashes com Argon2id em Python.
Criptografia
Chaves pública e privada do zero: o que uma assinatura prova, por que a chave privada fica em segredo e um lab Ed25519 em que um arquivo alterado falha.