Pular para o conteúdo
Novo

DeepSeek V4.1 Flash grátis por 7 dias: 10M tokens por dia após qualquer recarga. Até 30/11.

Como funciona

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.

Iniciante10 min de leituraPor NotHoly

Codificação, criptografia e hash transformam dados em outra coisa, e por isso as pessoas misturam os três. Eles têm objetivos diferentes. A codificação muda a forma como os dados são escritos, então qualquer pessoa consegue desfazê-la. A criptografia esconde os dados de quem não tem uma chave, e você desfaz o processo com essa chave. O hash gera uma impressão digital curta que não volta ao conteúdo original. Se você guardar só uma frase: Base64 não é criptografia, e um hash não esconde nada de entradas curtas.

Este artigo separa as três ideias e pede que você execute cada uma no terminal com o mesmo texto. Assim você compara os resultados com os seus próprios olhos.

Antes de começar

Você precisa de um terminal com base64, sha256sum e openssl. No Windows 11, os comandos abaixo rodam no Git Bash, que vem com o Git para Windows. Há também uma versão em PowerShell para o passo do hash. Você não precisa saber criptografia antes, mas ler o artigo sobre a cifra de César ajuda a entender a ideia de chave.

Todos os comandos do laboratório são seguros para rodar na sua máquina. Use um arquivo de teste, não um segredo de verdade.

Três trabalhos diferentes

As três operações respondem a três perguntas diferentes.

Operação Pergunta que responde Precisa de chave? Pode ser desfeita?
Codificação Como represento estes bytes como texto ou num formato que outro sistema espera? Não Sim, por qualquer pessoa
Criptografia Quem pode ler estes dados? Sim Sim, por quem tem a chave certa
Hash Estes dados mudaram, ou dois valores são iguais? Não Não, por projeto

Tenha esta tabela em mente durante o laboratório. O resto do artigo explica cada linha.

A codificação muda a representação

Codificação reescreve os dados em outra forma para que um sistema consiga transportá-los. O Base64 é o exemplo clássico. Ele pega bytes e os escreve com 64 caracteres imprimíveis: A a Z, a a z, 0 a 9, + e /, com = usado como preenchimento. A RFC 4648 define o formato. Anexos de e-mail, data URLs e muitos payloads de API usam Base64 porque o canal espera texto.

O Base64 não tem segredo. A tabela de conversão é pública e fixa. Qualquer ferramenta que conheça a regra consegue transformar a saída de volta na entrada. Esse é o propósito da codificação: interoperabilidade, não sigilo.

A criptografia esconde os dados atrás de uma chave

Criptografia pega dados legíveis, chamados de texto claro, e os transforma com um algoritmo e uma chave em texto cifrado. Quem não tem a chave não deveria aprender nada útil com o texto cifrado. Quem tem a chave consegue decifrar.

Existem duas famílias. A criptografia simétrica usa a mesma chave secreta para cifrar e decifrar. O AES é a escolha mais comum. A criptografia assimétrica usa uma chave pública e uma chave privada. Este artigo usa criptografia simétrica, porque o comando do OpenSSL no laboratório também usa.

Criptografia boa depende de mais do que o algoritmo. Você precisa escolher um modo seguro, gerar chaves com uma fonte aleatória confiável e proteger a chave. O comando do OpenSSL no laboratório usa uma senha e PBKDF2 para derivar a chave. O texto de ajuda do OpenSSL diz que o PBKDF2 usa 10.000 iterações por padrão, a não ser que você troque esse valor com -iter.

O hash cria uma impressão digital

Uma função de hash criptográfico recebe uma entrada de qualquer tamanho e devolve uma saída de tamanho fixo. O SHA-256 está especificado na FIPS 180-4, e a saída dele tem sempre 256 bits, escritos como 64 caracteres hexadecimais. Duas propriedades importam para quem está começando:

  • A mesma entrada sempre gera a mesma saída.
  • Uma pequena mudança na entrada deve mudar a saída de forma que ela pareça não ter relação com a anterior. Boas funções de hash são desenhadas para que achar duas entradas com a mesma saída seja inviável.

O hash é de mão única. Nada na saída mostra o texto original. Você consegue verificar se uma entrada candidata produz um hash conhecido. Não consegue recuperar a entrada só a partir do hash, a não ser adivinhando e testando.

Lembre que um hash é uma impressão digital, não uma fechadura. Qualquer pessoa pode calcular o SHA-256 de um arquivo público. O hash prova que duas cópias são iguais. Ele não esconde o arquivo.

Por que isso importa

A maior parte dos erros reais de segurança nessa área vem de usar a ferramenta errada para o trabalho.

  • Um desenvolvedor guarda uma chave de API em Base64 e chama aquilo de "criptografado". Quem vê o valor decodifica em um comando.
  • Uma equipe confere um download com hash, mas o hash está publicado na mesma página do arquivo, servida pelo mesmo servidor comprometido. A verificação prova só que o arquivo bate com a página, nada além disso.
  • Uma aplicação web guarda senhas com SHA-256 puro. Um banco de dados roubado pode ser atacado com chutes rápidos, porque o SHA-256 foi feito para ser rápido. A orientação do OWASP sobre armazenamento criptográfico diz que senhas devem ser protegidas com algoritmos seguros de hash de senha, em vez de criptografia reversível, e aponta para a Password Storage Cheat Sheet para os detalhes. Escolhas comuns são funções lentas e com sal, como Argon2id, scrypt, bcrypt ou PBKDF2. O próximo artigo desta série trata do Argon2id.

Entender essa diferença cedo evita essas armadilhas.

Laboratório 1: codificar com Base64

Abra o Git Bash numa pasta vazia. Codifique uma frase curta e depois decodifique o resultado.

bash
echo -n 'hello lab' | base64

A saída que obtive nesta máquina, com OpenSSL 3.2.4 e Git Bash:

text
aGVsbG8gbGFi

Agora decodifique essa saída:

bash
echo -n 'aGVsbG8gbGFi' | base64 -d

Saída:

text
hello lab

Duas coisas para notar. Primeiro, nenhuma chave entrou na história. Segundo, o echo -n importa. Sem o -n, o echo acrescenta uma quebra de linha, e a saída em Base64 muda. Rode echo 'hello lab' | base64 e compare: obtive aGVsbG8gbGFiCg==. Aqui, o Base64 transforma 9 bytes em 12 caracteres, então a saída fica mais longa que a entrada.

Pergunte a si mesmo: alguém sem nenhum segredo conseguiria desfazer isso? Consegue. É esse teste que separa codificação de criptografia.

Laboratório 2: gerar hash com SHA-256

Passe a mesma frase pelo SHA-256:

bash
echo -n 'hello lab' | sha256sum

Saída:

text
8fc6baba79a0d60b37dee612ccc1ec096ef52dba8cb0a24a6451e8bfb0e4d761 *-

Agora acrescente um ponto de exclamação e rode de novo:

bash
echo -n 'hello lab!' | sha256sum

Saída:

text
36902fb7fdea33458ad09dfeb52118dc47f99a8ca2b9001080366d55511de915 *-

Os dois hashes não têm nenhum padrão visível em comum. Um único caractere mudou a saída inteira. Os dois têm 64 caracteres hexadecimais, ou seja, 256 bits.

O - no fim indica que a entrada veio da entrada padrão, não de um arquivo. O * antes dele é a marca de modo binário que o sha256sum do Git Bash imprime. Outros sistemas podem imprimir dois espaços, e o hash é o mesmo. O hash de um arquivo funciona do mesmo jeito.

Calcule o hash de um arquivo e detecte uma mudança

Crie um arquivo pequeno e calcule o hash:

bash
echo 'secret note' > note.txt
sha256sum note.txt

Na minha máquina, com quebras de linha no formato Unix no arquivo, a saída foi:

text
b5f891a5e064fec661025d0b0ec2de157487a6c2e5cc46dc0971fee56f86c645 *note.txt

Mude o arquivo, mesmo que seja um único caractere, e calcule o hash de novo. O valor vai ser outro. É assim que as verificações de integridade funcionam. A verificação diz que o arquivo mudou. Não diz o que mudou, e não impede um atacante de alterar o arquivo e o hash publicado ao mesmo tempo.

Alternativa no PowerShell do Windows

Se preferir o PowerShell, o Windows tem um comando embutido:

powershell
Get-FileHash note.txt -Algorithm SHA256

Confira na saída a linha Hash, que mostra 64 caracteres hexadecimais. O hash depende dos bytes exatos do arquivo. O Set-Content do PowerShell grava quebras de linha do Windows (CRLF), que são diferentes do LF do exemplo em Bash acima. Na minha máquina, um arquivo gravado dessa forma gerou este hash:

text
406A5646AE75CA75D032F306ABD33085DC9F656E3109BB962AEAB335EEC9ED85

Os mesmos bytes calculados com sha256sum no Git Bash deram o mesmo valor, em minúsculas. Se o seu hash for diferente do exemplo em Bash, mas bater com o resultado do PowerShell para o seu próprio arquivo, a causa são as quebras de linha.

Laboratório 3: criptografar um arquivo com OpenSSL

Crie uma nota e criptografe com AES-256-CBC. O OpenSSL vai pedir uma senha. Escolha uma que você lembre e use só neste laboratório.

bash
echo 'secret note' > note.txt
openssl enc -aes-256-cbc -pbkdf2 -salt -in note.txt -out note.enc

O OpenSSL pede a senha, e o arquivo criptografado é gravado em note.enc. A opção -salt acrescenta um sal aleatório, então criptografar o mesmo arquivo duas vezes gera saídas diferentes. Um arquivo criptografado com -salt começa com o texto ASCII Salted__. Confirmei isso na minha máquina. O resto do arquivo é binário e ilegível.

Agora descriptografe:

bash
openssl enc -d -aes-256-cbc -pbkdf2 -in note.enc

Digite a mesma senha. Saída:

text
secret note

A descriptografia só funciona com a senha certa. Testei com uma senha errada. O OpenSSL mostrou bad decrypt e saiu com erro.

A criptografia, sozinha, não detecta adulteração

Em seguida, altere um byte do arquivo criptografado e tente descriptografar. Inverti um bit dentro do bloco cifrado de uma cópia chamada tampered.enc. A descriptografia falhou com bad decrypt, e o comando saiu com status 1.

Essa falha é um acidente de sorte do preenchimento do modo CBC. Outras mudanças podem gerar lixo sem nenhum erro. A lição é que a criptografia simples não dá um sinal confiável de que o texto cifrado foi modificado. Sistemas que precisam de sigilo e integridade ao mesmo tempo usam criptografia autenticada, como o AES-GCM, ou acrescentam um código de autenticação de mensagem. É um tema avançado, mas explica por que um arquivo criptografado não é automaticamente um arquivo confiável.

As três lado a lado

Passe o mesmo texto por cada operação e compare:

Operação Comando Saída para hello lab (observada)
Codificação echo -n 'hello lab' | base64 aGVsbG8gbGFi
Hash echo -n 'hello lab' | sha256sum 8fc6baba...e4d761
Criptografia openssl enc ... -in note.txt Dados binários, precisa da senha para ler

Pergunte o que cada saída permite fazer:

  • O Base64 permite que qualquer pessoa recupere hello lab.
  • O hash permite verificar se uma entrada candidata é hello lab, mas não recuperar a entrada só a partir do hash.
  • O arquivo criptografado permite recuperar secret note apenas com a senha.

Erros comuns

Chamar Base64 de "criptografia" ou "ofuscação" para segredos. O Base64 não esconde nada. Quem vê uma string em Base64 consegue decodificá-la. Guarde segredos num gerenciador de segredos ou num armazenamento criptografado, não em forma codificada.

Usar hash como fechadura. O hash é de mão única, mas entradas curtas ou comuns podem ser adivinhadas. Calcule o hash de hello lab e um atacante com uma lista de frases comuns recupera o texto sem quebrar o SHA-256. Por isso o hash de senhas precisa de sal e de algoritmos lentos.

Usar SHA-256 puro para senhas. O SHA-256 é rápido por projeto, o que serve para somas de verificação de arquivos e não serve para guardar senhas. Use uma função de hash de senha feita para isso.

Confiar num hash que vem do mesmo lugar que o arquivo. Um checksum na mesma página comprometida não prova nada. Obtenha o hash esperado por um canal separado e confiável, ou verifique uma assinatura digital.

Esquecer que a criptografia exige gestão de chaves. O laboratório usa uma senha digitada no prompt. Sistemas reais precisam guardar, trocar e proteger chaves. Perder a chave significa perder os dados.

Escrever sua própria criptografia. Use bibliotecas e protocolos estabelecidos. Os comandos do laboratório servem para aprender, não são modelo para sistemas de produção.

Como ir além

Repita os três laboratórios com outra frase e depois com um arquivo de alguns kilobytes. Veja que a saída em Base64 cresce cerca de um terço, que o hash continua com 64 caracteres e que o arquivo criptografado cresce só pelo cabeçalho e pelo preenchimento.

Depois, leia sobre hash de senhas. O problema ali não é o hash em si, e sim o custo de adivinhar. O próximo artigo da série, Como funciona o hash de senhas com Argon2id, explica sal, fator de trabalho e por que hashes lentos importam. Se quiser revisar o lado das cifras antes, leia Cifra de César em Python. Ele mostra uma chave e um algoritmo numa forma que você consegue testar.

Ao estudar protocolos reais, observe três coisas em cada projeto: o que ele codifica, o que ele criptografa e o que ele calcula como hash. A maior parte da confusão some quando você pergunta qual dos três trabalhos cada parte está fazendo.

Fontes

Fontes

  1. RFC 4648: The Base16, Base32, and Base64 Data Encodings
  2. FIPS 180-4: Secure Hash Standard (SHS), with update 1
  3. OWASP Cryptographic Storage Cheat Sheet

Mais em Criptografia

Criptografia

Senhas e hash com Argon2id

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.

Intermediário11 min de leitura