Compartilhando chaves AES utilizando RSA com OpenSSL

Gustavo Oliveira
b2w engineering
Published in
6 min readSep 23, 2020

Se você trabalha com desenvolvimento backend moderno, é inevitável que um dia você vá integrar sua aplicação com serviços externos. Quando dados sensíveis são compartilhados nesta integração, é importante criptografá-los para fornecer uma camada adicional de proteção, caso haja vazamentos ou ciberataques.

Criptografia simétrica

Por muitos anos, criptografia era alcançada utilizando uma chave compartilhada entre dois lados (transmissor e receptor), utilizada para criptografar uma mensagem por um dos lados e descriptografar do outro, por isso o nome simétrica. A criptografia simétrica ainda é amplamente usada, mas possui pontos fracos.

Ponto fraco em criptografia simétrica

Para estabelecer uma comunicação utilizando criptografia simétrica, um lado deve gerar a chave e enviar para o outro. Anteriormente isso era feito em encontros pessoais. No mundo de serviços online, essa não é uma opção viável, já que a distância física entre os lados pode ser grande e a implementação deve ser rápida.

Compartilhar a chave online introduz alguns riscos de segurança, já que, se descoberta por alguém capaz de interceptar as mensagens (ex: funcionários com acesso a rede), essa pessoa pode visualizar o conteúdo original das mesmas, alterá-las ou até mesmo se passar como o transmissor original sem que nenhum dos lados perceba (man-in-the-middle attack).

Criptografia assimétrica

Em criptografia assimétrica, é utilizado um par de chaves pública / privada, sendo uma utilizada para criptografar uma mensagem e a outra para descriptografar. Atualmente, o algoritmo mais popular para criptografia assimétrica é RSA (Rivest-Shamir-Adleman), que inclui os seguintes princípios:

  1. A chave privada é privada;
  2. A chave pública pode ser compartilhada;
  3. A chave pública deriva da chave privada;
  4. Não é possível chegar até a chave privada a partir da chave pública;
  5. Uma mensagem criptografada pela chave privada só pode ser descriptografada com a chave pública correspondente;
  6. Uma mensagem criptografada pela a chave pública só pode ser descriptografada com a chave privada correspondente.

Implementação RSA

Digamos que Alice quer enviar uma mensagem criptografada para Bob 😅. Utilizando criptografia RSA, cada um gera um par de chaves e compartilha sua chave pública com o outro. Alice criptografa sua mensagem, utilizando a chave pública de Bob e em seguida com sua chave privada, antes de finalmente enviá-la para Bob. Bob recebe a mensagem criptografada, a descriptografa com a chave pública de Alice e em seguida com sua chave privada, para chegar a mensagem original.

Por que criptografar com a chave privada?

Uma dúvida bastante comum neste processo é entender por qual motivo Alice iria querer criptografar a mensagem com sua chave privada, já que qualquer um com sua chave pública pode descriptografá-la.

O fato da mensagem ser descriptografada com a chave pública de Alice garante que ela foi criptografada com sua chave privada (princípio RSA #6). Dessa forma, assumindo que apenas Alice conhece sua chave privada, Bob pode verificar que a mensagem foi enviada por Alice. Este processo é conhecido como assinar a mensagem.

Por que não utilizar simplesmente criptografia RSA?

RSA não foi desenvolvido para processar grandes quantidades de dados. Neste cenário, um algoritmo simétrico como AES (Advanced Encryption Standard) é recomendado.

Segue um exemplo comparativo entre os algoritmos RSA e AES, utilizados para criptografar e descriptografar um arquivo csv de 100.000 linhas com as colunas nome, email e idade com Go. Código disponível neste repositório.

RSA
Criptografar: 30.31 s
Descriptografar: 569.62 s

AES
Criptografar: 1.36 s
Descriptografar: 1.20 s

A criptografia foi aplicada aos valores textuais, não aos arquivos diretamente, levando em consideração que estes números podem variar conforme a implementação utilizada. No caso citado, foram usados RSA COM OAEP (Optimal asymmetric encryption padding) e hash SHA256, e AES com GCM (Galois/Counter Mode).

AES + RSA

Uma maneira comum de resolver este problema, é criptografar / descriptografar o conteúdo desejado com AES e compartilhar a chave AES utilizando RSA. Dessa maneira, é possível se beneficiar da eficiência do AES e minimizar seu ponto fraco (envio da chave).

Implementação AES + RSA com OpenSSL

OpenSSL é uma ferramenta robusta de nível comercial para protocolos TLS (Transport Layer Security) e SSL (Secure Sockets Layer) e também uma biblioteca criptográfica generalizada. Foi escolhido utilizar o OpenSSL neste artigo, pois é amplamente utilizado e disponível em diversas plataformas por muitos anos.

Abaixo estão definidos os passos de uma implementação com AES e RSA, para estabelecer uma comunicação criptografada entre Alice e Bob, utilizando OpenSSL em sistemas UNIX.

1. Generate RSA key pairs

Alice gera uma chave privada e a armazena em um arquivo private.pem.

openssl genrsa -out private.pem

O tamanho recomendado para chaves RSA atualmente, considerando o poder computacional para ataques de força bruta, é 2048 bits, padrão neste comando.

Alice extrai a chave pública a partir da chave privada (princípio RSA #3) para um novo arquivo public.pem.

openssl rsa -in private.pem -pubout -out public.pem

2. Compartilhar chaves públicas

Alice e Bob compartilham seus arquivos pem públicos entre si.

Uma chave RSA de 2048 bits pode ser reutilizada por um longo período, mas é recomendado que seja trocada pelo menos uma vez por ano, dependendo do interesse de terceiros em descobri-la.

3. Gerar chave AES

Neste exemplo, é utilizado o algorítimo AES com modo de operação 256 bits CBC (Cipher-block chaining). Este modo requer uma chave com 32 bytes e um vetor de inicialização (iv) com 16 bytes. Alice gera a chave e o vetor no formato hexadecimal e os armazena em variáveis para uso subsequente.

AES_KEY=$(openssl rand -hex 32)
AES_IV=$(openssl rand -hex 16)

É recomendado gerar um novo par de chave / vetor a cada uso, mas é possível reutilizar a chave por um tempo e trocar somente o vetor, que não precisa ser criptografado.

A função para criptografia do OpenSSL não suporta o modo de operação GCM.

4. Criptografar dados com a chave AES

Alice criptografa um arquivo texto data.csv que deseja enviar para Bob.

openssl enc -aes-256-cbc -K $AES_KEY -iv $AES_IV -in data.csv -out data.csv.enc

5. Criptografar chave AES com RSA

Alice criptografa a chave AES utilizando a chave pública de Bob para um arquivo aes_key.enc.

echo $AES_KEY | openssl rsautl -encrypt -pubin -inkey public.pem -oaep -out aes_key.enc

O argumento -oaep especifica o uso de padding OAEP, que é o recomendado.

6. Assinar mensagem

Alice cria um arquivo de assinatura aes_key.env.sig a partir de aes_key.enc, utilizando sua chave privada.

openssl dgst -sha256 -sign private.pem -out aes_key.enc.sig aes_key.enc

7. Enviar arquivo e chave AES criptografados, assinatura e vetor

Alice envia o arquivo criptografado data.csv.env, a chave AES criptografada aes_key.enc, o arquivo de assinatura aes_key.enc.sig e o vetor para Bob.

8. Verificar assinatura

Bob verifica se os dados recebidos vieram de Alice, comparando se o hash do arquivo aes_key.enc corresponde ao arquivo de assinatura aes_key.enc.sig, descriptografado com a chave pública de Alice.

openssl dgst -sha256 -verify public.pem -signature aes_key.enc.sig aes_key.enc

O argumento -sha256 especifica o hash utilizado para criptografar o arquivo.

9. Descriptografar chave AES

Bob descriptografa o arquivo aes_key.enc, utilizando sua chave privada para chegar até a chave AES gerada por Alice.

AES_KEY=$(openssl rsautl -decrypt -inkey private.pem -in aes_key.enc)

10. Descriptografar dados

Bob descriptografa o arquivo data.csv.env e finalmente consegue visualizar seu conteúdo original.

openssl enc -d -aes-256-cbc -K $AES_KEY -iv $AES_IV -in data.csv.enc -out data.csv

Conclusão

O algoritmo AES é eficiente para criptografia em arquivos grandes, mas compartilhar a chave apresenta alguns riscos. Uma forma de minimizar esse risco é utilizar o algoritmo RSA para enviar a chave. O OpenSSL fornece uma fácil implementação para uma comunicação criptografada, usando esta lógica e que pode ser automatizada.

Se você busca uma oportunidade de desenvolvimento, trabalhando com inovação em um negócio de alto impacto, acesse o portal B2W Carreiras! Nele, você consegue acessar todas as vagas disponíveis. Venha fazer parte do nosso time!

--

--