Criptografia simétrica vs. assimétrica: exemplos práticos em Python
Josh Amata
15 de maio de 2024
0 minutos de leituraA criptografia simétrica e a assimétrica são as duas formas mais comuns de proteger dados confidenciais com criptografia. Esses métodos usam chave(s) para transformar uma mensagem não criptografada em uma mensagem criptografada (um texto cifrado), extremamente difícil de decifrar sem a(s) chave(s) correta(s). A criptografia simétrica usa uma única chave para criptografar e descriptografar dados. Já a criptografia assimétrica usa um par de chaves — uma pública e outra privada — para criptografar e descriptografar dados confidenciais.
Sistemas seguros de transmissão e armazenamento de dados — que priorizam a confidencialidade — usam esses métodos de criptografia com frequência. Por exemplo, aplicativos de mensagens com criptografia de ponta a ponta criptografam as mensagens antes de enviá-las. Essa abordagem impede que um invasor intercepte a comunicação e leia mensagens em texto claro por meio de um ataque man-in-the-middle. O conteúdo de uma mensagem criptografada é ilegível para um invasor.
A criptografia simétrica e a assimétrica também são úteis em outros casos, como no armazenamento de informações confidenciais, incluindo senhas e prontuários médicos. Em geral, os sistemas criptografam essas informações antes de armazená-las em servidores ou compartilhá-las entre computadores.
Aplicações como TLS/SSL também usam esses métodos. Durante o handshake, quando o servidor envia sua chave pública ao cliente, o cliente gera um segredo pré-mestre aleatório e o criptografa usando a chave pública do servidor. Em seguida, o servidor descriptografa esse segredo pré-mestre com sua chave privada. Depois, o servidor e o cliente geram, de forma independente, o segredo mestre a partir do segredo pré-mestre e de outros parâmetros do handshake.
Como usam os mesmos parâmetros, o cliente e o servidor geram o mesmo segredo mestre, que a aplicação usa para gerar as chaves de sessão. Essas chaves simétricas ajudam a criptografar e descriptografar dados durante a sessão, garantindo uma comunicação segura entre o servidor e o cliente. Esse processo usa a criptografia assimétrica para compartilhar chaves com segurança e sem a necessidade de confiança, além do compartilhamento seguro de chaves simétricas para uma transmissão de dados rápida e confiável.
Os dois métodos ajudam a reduzir riscos de segurança que comprometem os dados, como acesso não autorizado, interceptação e adulteração, roubo e violações de privacidade. Neste guia, vamos explicar a criptografia simétrica e assimétrica, implementá-las em Python e explorar as práticas recomendadas.
Pré-requisitos
Para acompanhar este tutorial, você precisará de:
Conhecimentos práticos de Python
Uma cadeia de ferramentas Python (versão 3.7 ou superior), incluindo o pip, instalada
Uma conta da Amazon Web Services (AWS). Criar uma conta e usar determinados serviços é gratuito.
Entenda a criptografia simétrica
A criptografia simétrica usa a mesma chave para criptografar e descriptografar, o que a torna mais rápida e eficiente do que a criptografia assimétrica. Em geral, ela segue a sequência abaixo.
Geração da chave: o remetente ou um terceiro confiável gera uma chave secreta e a compartilha com segurança com o destinatário pretendido.
Criptografia: o remetente aplica um algoritmo de criptografia simétrica, como o data encryption standard (DES), o triple DES (3DES) ou o advanced encryption standard (AES), à mensagem em texto simples e à chave secreta compartilhada. Esse processo converte o texto simples em texto cifrado.
Transmissão de dados: o remetente transmite o texto cifrado ao destinatário por um canal inseguro, como a internet.
Descriptografia: o destinatário aplica o mesmo algoritmo de criptografia simétrica, em sentido inverso, usando a chave compartilhada. Esse processo descriptografa o texto cifrado e recupera a mensagem original em texto simples.
Por ser mais eficiente e rápida, a criptografia simétrica é preferível à assimétrica em tarefas complexas, como criptografar arquivos, bancos de dados ou até partições inteiras de disco. Com esse método, mesmo que esses dados armazenados sejam comprometidos, eles continuam ilegíveis e criptografados sem a chave correta.
Algoritmos de criptografia simétrica
Vamos conhecer melhor o DES, o 3DES e o AES e entender como a criptografia envelope ajuda no gerenciamento de chaves.
Data encryption standard (DES)
O DES é um algoritmo de criptografia simétrica popular desde a década de 1970. Ele usa uma chave de 56 bits, o que limita o conjunto de chaves a 256 (2 elevado a 56) chaves possíveis. O DES foi relativamente seguro por cerca de duas décadas, mas hoje é fácil quebrá-lo com ataques de força bruta que usam o poder computacional moderno.
Triple data encryption standard (3DES)
O 3DES é uma versão aprimorada do DES que usa três chaves DES. Ele oferece um nível de segurança maior, de 112 bits. No entanto, ainda é ineficiente, pois exige uma chave de 168 bits para garantir 112 bits de segurança.
Padrão de criptografia avançado (AES)
O AES surgiu na década de 1990 e é o padrão moderno para criptografia simétrica. Suas chaves oferecem níveis de segurança de 128, 196 ou 256 bits. A maioria das aplicações usa chaves de 128 bits, já que a diferença de segurança entre 128 e 256 bits é insignificante. O AES é mais rápido e seguro que o 3DES.
Criptografia envelope
Um dos principais desafios da criptografia simétrica é o gerenciamento de chaves. O vazamento de uma chave é desastroso nesse tipo de criptografia, pois a mesma chave é usada para criptografar e descriptografar. A criptografia envelope resolve esse problema. Ela usa uma chave de criptografia de dados (DEK) e uma chave de criptografia de chaves (KEK). A DEK é a chave principal que a aplicação usa para criptografar dados, enquanto a KEK criptografa a DEK.
Essa criptografia em duas camadas oferece mais segurança, pois um ataque bem-sucedido exigiria as duas chaves. Ambientes de computação em nuvem costumam usar criptografia envelope por sua maior segurança, flexibilidade e escalabilidade. Como você verá adiante, os provedores de nuvem geralmente oferecem interfaces úteis para usar a criptografia envelope e proteger sua chave mestra (KEK) contra exposição.
Como implementar criptografia simétrica em Python
Vamos criar uma aplicação Python para criptografia e descriptografia usando criptografia envelope simétrica. O AWS Key Management Service (KMS) oferece criptografia envelope para o gerenciamento de chaves e o AWS Encryption SDK para se comunicar com o serviço.
Primeiros passos
Para começar, crie um diretório para o projeto:
Em seguida, siga estas etapas para criar uma chave simétrica do KMS no painel da AWS. Essa chave do KMS será sua chave mestra do cliente (CMK).
Configure as permissões de acesso à chave e copie o nome de recurso da Amazon (ARN) na seção General configuration do painel da chave.

O ARN é o identificador da sua CMK para interagir com o AWS Encryption SDK. Ele é a KEK que criptografa a DEK gerada.
Em seguida, instale a AWS CLI e configure usando o seguinte comando:
Ao configurar a AWS CLI, verifique se o perfil tem as permissões corretas para a CMK. Essa configuração permite que a aplicação se comunique corretamente com o AWS KMS usando as credenciais salvas.
Como criar o restante da aplicação
Vamos usar os pacotes aws-encryption-sdk e argparse para criar o restante da aplicação. O aws-encryption-sdk é uma implementação do AWS Encryption SDK para Python. Instale esses pacotes com este comando do pip:
Agora, crie um arquivo sym_encryptor.py e adicione este código para importar os módulos necessários:
Em seguida, adicione o código abaixo para criar as classes do cliente e do provedor de chaves:
A classe EncryptionSDKClient oferece métodos de alto nível para o cliente, como encrypt, decrypt e stream, para criptografar dados. O código configura a classe StrictAwsKmsMasterKeyProvider com uma lista de chaves mestras do AWS KMS para criptografia e descriptografia.
Informe o ARN identificador da CMK que você criou anteriormente. Com o ARN da CMK, o código consegue derivar uma chave a partir dela para criptografar o texto simples.
O aws-encryption-sdk gera, criptografa e descriptografa automaticamente a chave de dados derivada da CMK. Essa automação simplifica o gerenciamento de chaves.
Como criar a função de criptografia
Adicione a seguinte função ao script para criar a função de criptografia:
Essa função recebe a mensagem como dados binários e a criptografa usando o método encrypt() do cliente. O método encrypt recebe os dados que serão criptografados, a classe do provedor de chaves e o contexto de criptografia.
Ao passar a classe do provedor de chaves criada anteriormente, o cliente gera uma chave de criptografia de dados a partir da CMK e criptografa os dados. O cliente retorna o texto cifrado e um cabeçalho do criptografador, que contém informações para verificar a autenticidade. O contexto de criptografia é um dicionário com informações do cabeçalho do criptografador retornado pelo cliente.
Como criar a função de descriptografia
Adicione as linhas de código a seguir ao script para criar a função de descriptografia:
Essa função recebe o texto cifrado e chama o método decrypt() do cliente, passando o provedor de chaves e o texto cifrado como argumentos. O método decrypt funciona de forma semelhante ao método encrypt. Ele deriva uma chave de dados a partir da CMK configurada e reverte a criptografia aplicando aos dados a mesma chave e o mesmo algoritmo. Esse método retorna o texto descriptografado e um cabeçalho do descriptografador, semelhante ao cabeçalho do criptografador. Em aplicações reais, esses cabeçalhos ajudam a verificar os dados, pois ambos contêm as mesmas informações, incluindo o conjunto de cifras, o ARN e o contexto de criptografia.
Como criar uma aplicação de linha de comando
Para facilitar os testes, vamos transformar nossa aplicação em uma aplicação de linha de comando que interpreta argumentos. Adicione o seguinte código:
Esse código interpreta os argumentos da linha de comando. Ele define uma opção para a chave e opções para escolher entre os modos de criptografia e descriptografia. Salve o arquivo e execute o seguinte comando:
A saída é a seguinte:
Como testar a aplicação
Para testar a aplicação, primeiro crie um arquivo de texto qualquer, como o exemplo abaixo:
Execute o arquivo na aplicação, passando o nome do arquivo e a opção de modo de criptografia -e.
Essa ação cria um novo arquivo, encrypted.bin.
A saída será semelhante a esta:
Esse arquivo representa o texto cifrado criado pela nossa aplicação. Podemos enviá-lo ao destinatário, que — assim como qualquer outra pessoa — precisa ter as permissões de acesso corretas no KMS para a CMK.
Como descriptografar o arquivo
Para simular o processo de descriptografia, execute o arquivo criptografado na aplicação:
Você verá uma notificação com a mensagem decryption complete.
O código cria um novo arquivo chamado decrypted.file no seu diretório, como mostrado abaixo:
Agora, recuperamos com sucesso o texto original após criptografar e descriptografar a mensagem usando criptografia envelope simétrica com o AWS KMS.
Entenda a criptografia assimétrica
Enquanto a criptografia simétrica que vimos usa a mesma chave para criptografar e descriptografar, a criptografia assimétrica usa um par de chaves: uma chave pública (que o usuário pode compartilhar publicamente pela internet ou por outros canais) e uma chave privada (que deve ser mantida em segredo).
Segurança e gerenciamento de chaves
Embora a criptografia simétrica geralmente seja mais rápida e eficiente, a criptografia assimétrica elimina as vulnerabilidades associadas ao compartilhamento seguro de uma chave entre remetente e destinatário. Com a criptografia assimétrica, podemos compartilhar livremente a chave pública com qualquer pessoa — até mesmo por canais inseguros —, pois esses arquivos só podem ser descriptografados com a chave privada correspondente. O destinatário mantém essa chave em segredo.
Se Alice quiser receber arquivos criptografados de Bob com segurança, ela deverá gerar um par de chaves pública e privada e enviar a chave pública a Bob. Ao recebê-la, Bob poderá criptografar os arquivos e transmiti-los pela internet. Alice, que tem a chave privada, será a única pessoa capaz de descriptografá-los.
Se Alice quiser enviar um arquivo criptografado a Bob, ele precisará criar seu próprio par de chaves pública e privada. Ao enviar a chave pública a Alice, ela poderá criptografar o arquivo com essa chave e enviá-lo a Bob. Então, Bob usará sua própria chave privada para descriptografar o arquivo.
Na criptografia assimétrica, cada pessoa precisa ter seu próprio par exclusivo de chaves pública e privada.
Casos de uso
As aplicações usam principalmente a criptografia assimétrica para a troca segura de chaves em protocolos TLS/SSL, comunicações seguras por e-mail com Pretty Good Privacy (PGP) e certificados digitais que verificam a identidade de quem envia ou recebe uma mensagem. A criptografia assimétrica oferece alta segurança sem exigir o compartilhamento seguro de chaves.
Algoritmos de criptografia assimétrica
Vamos conhecer alguns algoritmos populares de criptografia assimétrica para gerar pares de chaves, incluindo RSA, ElGamal e Curve25519.
Rivest-Shamir-Adleman (RSA)
O RSA é um dos algoritmos de criptografia assimétrica mais antigos e populares. Ele se baseia na dificuldade matemática de fatorar números compostos grandes em seus fatores primos.
A geração de chaves no RSA seleciona dois números primos grandes, calcula o módulo e a função totiente de Euler e deriva os componentes das chaves privada e pública. O RSA está presente em quase toda parte. Ele é extremamente seguro quando usa chaves suficientemente grandes — de 2048 bits ou mais —, mas exige mais processamento do que outros algoritmos.
ElGamal
O ElGamal se baseia na resolução do problema do logaritmo discreto. Esse algoritmo é mais rápido que o RSA, mas menos seguro e depende de chaves maiores para oferecer mais segurança. A geração de chaves no ElGamal seleciona um grupo cíclico e um gerador e, em seguida, calcula as chaves pública e privada usando exponenciação modular. A criptografia aleatoriza o texto simples e o multiplica pela chave pública do destinatário.
Curve25519
A Curve25519 é um dos algoritmos de criptografia de curva elíptica (ECC) mais rápidos e seguros. Ela funciona para trocas de chaves e assinaturas digitais, e seus algoritmos ECC oferecem alta segurança com chaves menores que as do RSA.
A ECC usa as propriedades matemáticas das curvas elípticas sobre corpos finitos. A geração de chaves envolve selecionar uma curva elíptica e um ponto-base e, em seguida, calcular as chaves pública e privada com base na multiplicação escalar na curva.
A ECC é usada principalmente em ambientes e dispositivos com recursos limitados, como sistemas de IoT e blockchain. Ela é mais eficiente em termos de processamento e mantém níveis de segurança semelhantes aos do RSA.
Implementando criptografia assimétrica em Python
Primeiro, crie um novo arquivo asym_encryptor.py no diretório do seu projeto usando o seguinte comando:
Importe as seguintes bibliotecas:
O módulo nacl.public contém classes para gerar pares de chaves privada/pública e métodos associados para lidar com a criptografia e a descriptografia. As classes PrivateKey e PublicKey inicializam as chaves correspondentes a partir de uma sequência de bytes, enquanto SealedBox criptografa e descriptografa mensagens destinadas a um par de chaves específico. O comando também importa as classes de exceção TypeError e CryptoError para o tratamento de erros.
Criando uma função auxiliar
Em seguida, crie uma função auxiliar para gerar pares de chaves:
Usando o algoritmo ECC Curve25519, essa função gera um objeto PrivateKey aleatório por meio do método generate() e a chave pública correspondente a essa chave privada. Em seguida, ela grava as chaves geradas nos respectivos arquivos.
Criando uma função para criptografar mensagens
Agora, adicione a seguinte função para criptografar mensagens usando a chave pública:
Essa função recebe uma mensagem em texto simples codificada em binário para criptografar e uma string que representa o local da chave pública. Em seguida, ela carrega e inicializa a chave pública com a classe PublicKey e inicializa um SealedBox usando a chave pública.
Criando a função de descriptografia
O PyNaCl oferece suporte à criptografia assimétrica por meio de duas classes: Box e SealedBox. A classe Box cria uma chave compartilhada usando a chave privada do remetente e a chave pública do destinatário para criptografar. Para descriptografar, ela exige as chaves privada e pública, fornecendo uma prova criptográfica da autoria do remetente.
Usamos a classe SealedBox para criar a função de descriptografia. Ela permite criptografar e descriptografar usando apenas um par de chaves, sem prova criptográfica de autoria. Inicializamos o SealedBox com a chave pública para criptografar e chamamos o método encrypt() com a mensagem que queremos criptografar. Em seguida, gravamos o texto cifrado correspondente em um arquivo no diretório de trabalho.
Adicione o seguinte código ao aplicativo:
Essa função recebe o texto cifrado a ser descriptografado e a chave privada. Ela carrega e inicializa a chave privada com a classe PrivateKey e inicializa um SealedBox com a chave privada para descriptografar. A função descriptografa a mensagem usando o método decrypt() e, em seguida, salva o texto descriptografado em um arquivo no diretório de trabalho.
Adicionando a análise de argumentos da linha de comando
Adicione a análise de argumentos da linha de comando usando o código a seguir para facilitar os testes do seu aplicativo:
Este código analisa os argumentos da linha de comando e define sinalizadores para escolher entre os modos de criptografia e descriptografia, gerar pares de chaves e informar arquivos.
Salve o arquivo e execute o seguinte comando:
A saída será:
Testando o aplicativo
Para testar o aplicativo, crie um arquivo de texto qualquer, como o exemplo abaixo:
Use o seguinte comando para gerar pares de chaves de teste antes de processar o arquivo com a criptografia:
A saída será:
Esse comando cria os pares de chaves privada/pública no diretório do projeto.
Agora, execute o seguinte comando para criptografar o arquivo de texto usando a chave pública gerada:
A saída será:
O aplicativo cria o texto cifrado e o salva como encrypted.bin no diretório do projeto. Esse arquivo criptografado é completamente ilegível. Só é possível descriptografá-lo com a chave privada correspondente à chave pública, como no exemplo abaixo:
A saída é:
private key decryption completed
O aplicativo salvou o arquivo descriptografado como decrypted.file no diretório do projeto. Leia o arquivo descriptografado usando o comando abaixo:
Ao concluir, você verá a saída “Hello World!!!”.
Agora, criptografamos e descriptografamos com sucesso um arquivo de texto simples usando criptografia assimétrica.
Implicações de segurança e práticas recomendadas para criptografia simétrica e assimétrica
Uma desvantagem importante da criptografia simétrica é a dificuldade de compartilhar chaves com segurança. Quanto maior o número de participantes no sistema, mais difícil fica distribuir as chaves. Embora a criptografia assimétrica contorne esse problema com pares de chaves pública/privada, a criptografia simétrica usa métodos como a criptografia envelope para alcançar níveis mais altos de segurança.
Veja algumas práticas recomendadas para criptografia simétrica e assimétrica:
Use ferramentas de provedores como Google Cloud Platform (GCP) ou AWS para gerenciar chaves em aplicações que usam chaves simétricas, como o AWS KMS.
Se possível, evite a criptografia RSA para preparar seus aplicativos para o futuro. Entre os riscos de segurança estão o uso de chaves pequenas demais (com menos de 2048 bits) — que hackers podem quebrar — e parâmetros de inicialização inadequados. É difícil implementar o RSA corretamente.
Escolha a criptografia simétrica para arquivos muito grandes. Ela oferece melhor desempenho do que as soluções assimétricas.
Ao escolher as chaves, selecione tamanhos adequados para o algoritmo de criptografia. Chaves pequenas demais criam brechas. Não use algoritmos inseguros, como o DES.
Não crie suas próprias soluções criptográficas, pois é fácil cometer erros.
Use ferramentas como Snyk para detectar problemas de segurança no seu código e sugerir recomendações. A plataforma da Snyk permite analisar, corrigir e priorizar vulnerabilidades de segurança no seu código, em dependências de código aberto, imagens de contêineres e configurações de infraestrutura como código (IaC).
Considere estes fatores ao decidir qual tipo de criptografia usar, já que cada técnica tem pontos fortes e fracos. Na prática, você pode combinar criptografia simétrica e assimétrica para equilibrar eficiência e segurança.
Usando a Snyk
Para descobrir como a Snyk pode encontrar vulnerabilidades durante o desenvolvimento, vamos usá-la para testar nosso código.
Primeiro, crie uma conta na Snyk. Você pode começar gratuitamente.

Depois de se cadastrar, a Snyk direciona você para a página a seguir, que pergunta onde está o código que você quer analisar — no GitHub, no Bitbucket Cloud ou por meio de uma CLI.

Selecione CLI e clique em Próxima etapa.
Na próxima tela, siga qualquer uma das etapas listadas para instalar a Snyk CLI e clique em Próxima etapa:

Em seguida, execute o seguinte comando para autenticar sua máquina:
Esse comando abre uma janela do navegador solicitando que você faça login. Ao concluir o processo, a Snyk CLI exibirá uma mensagem confirmando que a autenticação foi concluída com sucesso.

Agora, clique em Próxima etapa.

Clique em Código-fonte e acesse seu painel pelo caminho Configurações > Snyk Code. Ative a opção Habilitar Snyk Code no painel para executar a Snyk CLI no seu código. Em seguida, clique em Salvar alterações.

Para testar seu código, execute o seguinte comando no diretório do projeto:
Esse comando envia automaticamente os arquivos do seu código e os analisa em busca de vulnerabilidades:

A captura de tela acima mostra que nosso aplicativo tem uma vulnerabilidade de travessia de caminho, que permite que um invasor leia arquivos arbitrários. Podemos deixar essa vulnerabilidade no código do nosso aplicativo de demonstração, mas ela representa um vetor de ataque em bases de código mais funcionais.
Usamos a Snyk com sucesso para analisar nosso projeto em busca de vulnerabilidades.
Resumo
A criptografia simétrica e a assimétrica diferem na forma como usam as chaves para criptografar e descriptografar arquivos. A primeira usa uma única chave compartilhada, enquanto a segunda usa um par de chaves pública/privada.
Graças à sua implementação e eficiência computacional, a criptografia simétrica é mais adequada para criptografar grandes volumes de dados em repouso. A criptografia assimétrica é indicada para a transmissão de pequenas quantidades de dados, como em TLS/SSL e certificados digitais.
Neste guia, implementamos a criptografia envelope (que combina criptografia simétrica e assimétrica) usando o AWS Encryption SDK. Também implementamos criptografia e descriptografia assimétricas com a biblioteca Python pynacl. Ao longo do processo, exploramos os pontos fortes e fracos dos dois tipos de criptografia em relação a tamanhos menores de chave. Também mostramos como usar plataformas como a Snyk para analisar vulnerabilidades nos nossos aplicativos.
Agora que você sabe mais sobre criptografia, pode usar esses métodos para tornar seus aplicativos mais seguros para você e seus usuários. Em seguida, use a Snyk para garantir que sua abordagem seja segura.



