Hashing com SHA-256 em Criptografia

LinuxBeginner
Pratique Agora

Introdução

Bem-vindo ao mundo da criptografia! Neste laboratório, você terá experiência prática com um dos conceitos mais fundamentais da segurança moderna: o hashing criptográfico. Especificamente, trabalharemos com o algoritmo SHA-256.

Uma função de hash criptográfica é um algoritmo matemático que recebe uma entrada (ou 'mensagem') de qualquer tamanho e retorna uma string de bytes de tamanho fixo. Este resultado é tipicamente um 'resumo' (digest) ou 'hash'. O SHA-256, por exemplo, sempre produz um hash de 256 bits (32 bytes).

Estas funções possuem várias propriedades importantes:

  • Determinística: A mesma entrada sempre produzirá a mesma saída.
  • Unidirecional (One-way): É computacionalmente inviável reverter a função e encontrar a entrada original a partir do seu hash.
  • Efeito Avalanche: Uma pequena alteração na entrada (como mudar um único caractere) produzirá um hash de saída drasticamente diferente.

Ao longo deste laboratório, você usará a ferramenta de linha de comando openssl e um script Python simples para explorar essas propriedades e entender como o hashing é usado em cenários do mundo real, como verificar a integridade de arquivos e proteger senhas.

Propriedades da Função Hash

Nesta etapa, você usará a ferramenta de linha de comando openssl para explorar duas propriedades centrais das funções hash: serem determinísticas e o efeito avalanche. Uma função é determinística se a mesma entrada sempre produzir a mesma saída. O efeito avalanche significa que uma pequena alteração na entrada resulta em um hash de saída completamente diferente.

Primeiro, vamos gerar um hash SHA-256 para a string "hello". Usaremos o comando echo para passar a string para o openssl.

echo -n "hello" | openssl dgst -sha256

A flag -n no echo é importante; ela impede que o echo adicione um caractere de nova linha (newline) ao final da string, o que alteraria o hash resultante.

Você deverá ver uma saída como esta:

SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Agora, vamos executar exatamente o mesmo comando novamente para demonstrar a propriedade determinística.

echo -n "hello" | openssl dgst -sha256

Note que a saída é idêntica. Isso confirma que, para a mesma entrada, o hash SHA-256 é sempre o mesmo.

SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Em seguida, vamos demonstrar o efeito avalanche. Faremos uma alteração muito pequena na nossa string de entrada — mudando "hello" para "Hello" (com 'H' maiúsculo).

echo -n "Hello" | openssl dgst -sha256

Observe o novo hash:

SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

Compare este hash com o de "hello". Mesmo que apenas um bit da entrada tenha sido alterado (a capitalização da primeira letra), o hash resultante é completamente diferente. Este é o efeito avalanche em ação e é uma característica crítica para uma função de hash segura.

Calcular Hash de Arquivo

Nesta etapa, você calculará o hash SHA-256 de um arquivo de texto. Esta é uma prática comum usada para verificar a integridade de arquivos. Ao baixar um arquivo da internet, os websites frequentemente fornecem um checksum (um hash) para que você possa verificar se o arquivo não foi corrompido durante o download ou adulterado.

O script de configuração (setup script) para este laboratório já criou um arquivo chamado message.txt no seu diretório atual (~/project). Primeiro, vamos visualizar seu conteúdo usando o comando cat.

cat message.txt

Você verá o seguinte conteúdo:

This is a secret message.

Agora, vamos calcular o hash SHA-256 deste arquivo. A sintaxe é semelhante à que você usou antes, mas em vez de canalizar (piping) a entrada, você fornece o nome do arquivo como um argumento para o comando openssl dgst.

openssl dgst -sha256 message.txt

O comando processará o arquivo e imprimirá seu hash SHA-256. A saída será parecida com esta:

SHA2-256(message.txt)= 6432f513cfd40d47c8584494c0524468257e50dc1a0422f73becac85189543f8

Este hash serve como uma impressão digital digital única para o conteúdo atual de message.txt. Se alguém alterar até mesmo um único caractere no arquivo, o hash mudará completamente, como você verá em uma etapa posterior.

Gerar Múltiplos Hashes

Nesta etapa, você praticará mais a geração de hashes SHA-256 para diferentes entradas de string. Isso ajudará a reforçar sua compreensão de como qualquer entrada única produz um hash único. Continuaremos a usar o comando echo -n canalizado (piped) para o openssl para garantir que estamos apenas aplicando hash à string em si, sem caracteres extras.

Primeiro, vamos gerar o hash para a string "labex".

echo -n "labex" | openssl dgst -sha256

A saída será o hash SHA-256 para "labex":

SHA2-256(stdin)= 679e75b679886c5eaf8aaab88ddfc0181e6dae14cff346db8ba398bd7b2e31fe

Em seguida, vamos tentar uma string diferente, "crypto", para ver seu hash único.

echo -n "crypto" | openssl dgst -sha256

Como esperado, isso produz um hash completamente diferente:

SHA2-256(stdin)= da2f073e06f78938166f247273729dfe465bf7e46105c13ce7cc651047bf0ca4

Este exercício demonstra que cada pedaço distinto de dados, não importa quão pequeno ou grande, possui seu próprio valor de hash único. Esta propriedade é fundamental para como os hashes são usados para verificação de dados, em tecnologias blockchain e em assinaturas digitais.

Demonstrar Resistência a Colisão

Nesta etapa, você observará diretamente o efeito avalanche (avalanche effect) e o conceito de resistência a colisão (collision resistance) ao modificar ligeiramente o arquivo message.txt e ver como seu hash muda. Resistência a colisão significa que é extremamente difícil encontrar duas entradas diferentes que produzam o mesmo hash.

Primeiro, vamos recalcular o hash do arquivo original message.txt para tê-lo fresco em nossas mentes.

openssl dgst -sha256 message.txt

Você deverá ver o hash original novamente:

SHA2-256(message.txt)= 6432f513cfd40d47c8584494c0524468257e50dc1a0422f73becac85189543f8

Agora, faremos uma mudança muito pequena no arquivo. Adicionaremos um único ponto (.) ao final do arquivo. Podemos fazer isso facilmente usando o comando echo com o operador de redirecionamento >>, que anexa a saída a um arquivo.

echo "." >> message.txt

Você pode verificar se a alteração foi feita visualizando o conteúdo do arquivo novamente.

cat message.txt

Você verá o ponto no final:

This is a secret message.
.

Agora, vamos recalcular o hash do arquivo modificado.

openssl dgst -sha256 message.txt

O novo hash será:

SHA2-256(message.txt)= 4106e1c985a4ee1754fff76b8bffda0c4844679885cb70758f24cd43e771daac

Compare este novo hash com o original. Eles são completamente diferentes. Esta poderosa demonstração mostra que até mesmo uma alteração de um caractere em um arquivo resultará em um hash radicalmente diferente, facilitando a detecção de qualquer forma de adulteração.

Criar Hash de Senha

Nesta etapa, você sairá da linha de comando e escreverá um script Python simples para aplicar hash a uma senha. Armazenar senhas em texto simples é uma grande vulnerabilidade de segurança. A prática padrão é armazenar um hash da senha. Quando um usuário tenta fazer login, o sistema aplica hash à senha que ele inseriu e a compara com o hash armazenado.

O script de configuração já criou um arquivo vazio chamado hash_password.py. Agora você adicionará código a ele usando o editor de texto nano.

Abra o arquivo com nano:

nano hash_password.py

Agora, copie e cole o seguinte código Python no editor nano:

import hashlib

## The password we want to hash
password = "mysecretpassword"

## Hash functions in Python work on bytes, not strings.
## We must encode the string into bytes first, using UTF-8.
password_bytes = password.encode('utf-8')

## Create a new SHA-256 hash object.
sha256_hash = hashlib.sha256(password_bytes)

## Get the hexadecimal representation of the hash.
hex_digest = sha256_hash.hexdigest()

print(f"The password is: {password}")
print(f"The SHA-256 hash is: {hex_digest}")

Este script faz o seguinte:

  1. Importa a biblioteca hashlib, que fornece vários algoritmos de hashing.
  2. Define uma string de senha.
  3. Codifica a string em bytes usando .encode('utf-8'). Este é um passo crucial, pois as funções de hash operam em bytes.
  4. Cria um objeto de hash SHA-256 e o atualiza com os bytes da senha.
  5. Recupera o hash final em um formato hexadecimal legível usando .hexdigest().

Após colar o código, salve o arquivo e saia do nano pressionando Ctrl+X, depois Y e, em seguida, Enter.

Finalmente, execute seu script Python no terminal:

python3 hash_password.py

O script será executado e imprimirá a senha e seu hash SHA-256 correspondente:

The password is: mysecretpassword
The SHA-256 hash is: 94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263

Você usou com sucesso o Python para realizar hashing criptográfico, uma habilidade essencial para o desenvolvimento seguro de aplicações.

Resumo

Parabéns por concluir este laboratório! Você adquiriu experiência prática e direta com a função de hash criptográfico SHA-256.

Neste laboratório, você aprendeu:

  • As propriedades centrais das funções de hash: elas são determinísticas, unidirecionais (one-way) e exibem o efeito avalanche (avalanche effect).
  • Como usar o comando openssl dgst -sha256 em um ambiente Linux para calcular hashes tanto para strings quanto para arquivos.
  • A importância do hashing para verificar a integridade de arquivos (file integrity) e detectar adulterações.
  • Como usar a biblioteca hashlib do Python para gerar hashes SHA-256 programaticamente, uma tarefa comum em segurança de senhas (password security).

O hashing é um pilar da cibersegurança moderna. As habilidades que você praticou aqui são fundamentais para entender tópicos mais avançados, como assinaturas digitais, códigos de autenticação de mensagem (MACs) e tecnologia blockchain. Como próximo passo, você pode pesquisar sobre "salting" de senhas (salting passwords), que adiciona outra camada de segurança sobre o hashing.