Módulos Wifi

Criptografia de dados usando um ESP32

Eletrogate 28 de novembro de 2025

Introdução

O princípio básico por trás da criptografia é pegar uma informação legível e, pelo uso de um algoritmo, tornar essa informação ilegível. Porém, há uma ressalva: somente quem conhece o algoritmo e a chave usada para criptografar a informação terá acesso ao formato legível desta.

Está um pouco confuso? Tudo bem! Neste conteúdo, vamos criptografar informações na prática usando uma técnica simples de criptografia.

Fique comigo até o final!


Teoria por trás da criptografia

Em programação embarcada, usamos diversos operadores ao longo do código. Os operadores bitwise são pouco conhecidos pelos programadores web, mas muito usados pelos programadores de embarcados. Eles fazem parte dos operadores binários. Confira na imagem abaixo.

Tabela com os operadores de C/C++. Retirado de GeeksForGeeks.

Esses operadores operam sobre os bits por assim dizer, sendo extremamente eficientes no que tange ao consumo de memória.

Veja um exemplo:

Número (decimal) Descrição (8 bits)
10 00001010
50 00110010
255 11111111

Operações bitwise

Todos os operadores bitwise operam sobre os bits do número – as descrições apresentadas acima. Vamos analisar os operadores |, & e ^.

Suponha X e Y bits presentes em um número.

X Y X | Y X & Y X ^ Y
0 0 0 0 0
0 1 1 0 1
1 0 1 0 1
1 1 1 1 0

O operador | compara dois bits e, se um deles for 1, o resultado é 1; já o operador & só retorna 1 quando ambos os bits são 1; por fim, o operador ^ resulta em 1 quando ao menos um dos bits é 1, mas não ambos.

Veja exemplos práticos desses operadores:

Operação Descrição Resultado
10 | 50 00001010 | 00110010 00111010 = 58
10 & 50 00001010 & 00110010 00000010 = 2
10 ^ 50 00001010 ^ 00110010 00111000 = 56

Usaremos o operador ^, também conhecido como XOR na computação, algo como “OR Exclusive” ou “OU Exclusivo”, para realizar nossa criptografia.

Preste bastante atenção: podemos perceber que o número sofreu algo parecido com uma reescala: o número 10 foi para 50, quando usamos |, depois para 2 quando usamos &, e para 56 quando usamos ^.

Caracteres e ASCII

Você deve estar se pergunta “beleza Guilherme, você mostrou como transformar um número em outro… mas como podemos criptografar coisas com isso?” e eu respondo da seguinte forma: os caracteres que lemos também são números, portanto podemos convertê-los em outros números, tornando frases ilegíveis!

Dê uma olhada neste material sobre ASCII antes de continuar este tutorial. Tudo ficará mais claro.

Sendo assim, temos uma frase composta por caracteres (que também são números) e uma chave secreta (mais caracteres). Faremos a operação XOR em cada caractere da frase em relação a cada caractere da chave, e o resultado será uma frase criptografada.

Mas e para descriptografar? Bem… basta pegar a informação criptografada e fazer XOR pela chave que a criptografou anteriormente.

É simples assim!

Vamos a um exemplo prático. Nosso objetivo é criptografar a seguinte frase: “Eu odeio segundas-feiras”. Essa frase tem 24 caracteres, ou seja, 24 bytes.

Olhando apenas para os bytes, poderíamos reescrever a frase da seguinte forma: [69, 117, 32, 111, 100, 101, 105, 111, 32, 115, 101, 103, 117, 110, 100, 97, 115, 45, 102, 101, 105, 114, 97, 115].

Para criptografar a frase, usaremos a seguinte chave: [10, 5, 2, 11]. Note que a chave é menor que a frase. Sendo assim, faremos XOR um byte por vez e, quando acabarem os bytes da chave, retornaremos no primeiro byte.

A operação fica assim (para os primeiros 7 elementos):

Caractere Byte da frase Byte da chave XOR Equivalente
E 69 10 69  ^ 10 = 79 O
u 117 5 117 ^ 5  = 112 p
32 2 32  ^ 2  = 34
o 111 11 111 ^ 11 = 100 d
d 100 10 100 ^ 10 = 110 n
e 101 5 101 ^ 5  = 96 `
i 105 2 105 ^ 2  = 107 k

O resultado da criptografia é: Op”dn`kj*vgl?kfjy(dncwcx

Não sei para você, mas para mim está beeeem ilegível!

Note que até mesmo o espaço em branco é considerado um byte e, portanto, deve passar pela operação XOR também.

Vamos transformar essa técnica em código C/C++ e criar um sistema de criptografia com ESP32!


Diagrama do circuito

Para este tutorial, vamos aproveitar um circuito feito anteriormente aqui no blog.

O circuito é bem simples: basicamente conectamos os pinos de transmissão (TX) e recepção (RX) de dois ESP32. Veja o diagrama:

Circuito para o tutorial. Feito pelo autor.

Resumindo:

    • TX2 do ESP32-1 → RX2 do ESP32-2

    • RX2 do ESP32-1 → TX2 do ESP32-2

    • GND de ambos os ESP32 em comum


Configuração do projeto

Antes de começarmos, certifique-se de que você tenha o VSCode instalado com a extensão do Platformio habilitada. Caso não tenha o setup preparado, faça o passo a passo deste tutorial.

Configuração do Software

Vamos iniciar o desenvolvimento nomeando os ESP32 utilizados. Para simplificar, vamos chamar um ESP32 de “Encriptador” e o outro de “Cliente”.

O funcionamento do módulo encriptador é bastante simples: ele recebe a frase vinda do cliente, faz XOR caractere a caractere em uma chave secreta, e retorna o resultado ao cliente via UART.

Nossa chave secreta será a palavra “secreta”. Veja o código do módulo encriptador:

Código para o módulo encriptador

#include <Arduino.h>

#define NOME_DO_ESP32 "Encriptador"

const String CHAVE_SECRETA = "secreta";

// Função para encriptar e desencriptar usando XOR
String xorEncryptDecrypt(const String &input) {
 String output = "";

 for (size_t i = 0; i < input.length(); i++) {
 output += (char)(input[i] ^ CHAVE_SECRETA[i % CHAVE_SECRETA.length()]);
 }

 return output;
}

void setup() {
 Serial.begin(115200);
 Serial1.begin(9600, SERIAL_8N1, 16, 17);
 delay(1000);
}

void loop() {
 if (Serial1.available()) {
 String mensagem = Serial1.readString();

 for (size_t i = 0; i < mensagem.length(); i++) {
 Serial.print((uint8_t)mensagem[i]);
 Serial.print(" ");
 }

 Serial.println();

 Serial.println("Mensagem recebida: " + mensagem);

 mensagem = xorEncryptDecrypt(mensagem);

 Serial.println("Mensagem criptografada: " + mensagem);

 Serial1.print(mensagem);
 }
}

Código para o ESP32 cliente

#include <Arduino.h>

#define NOME_DO_ESP32 "Encriptador"

const String CHAVE_SECRETA = "secreta";

// Função para encriptar e desencriptar usando XOR
String xorEncryptDecrypt(const String &input) {
 String output = "";
 for (size_t i = 0; i < input.length(); i++) {
 output += (char)(input[i] ^ CHAVE_SECRETA[i % CHAVE_SECRETA.length()]);
 }
 return output;
}

void setup() {
 Serial.begin(115200);
 Serial1.begin(9600, SERIAL_8N1, 16, 17);
 delay(1000);
}

void loop() {
 delay(1000);

 String mensagem = "Olá, tudo bem?";

 Serial1.print(mensagem);

 while(!Serial1.available()) {
 delay(10);
 }

 String mensagemCriptografada = Serial1.readString();

 Serial.println("Mensagem original: " + mensagem);

 for (size_t i = 0; i < mensagem.length(); i++) {
 Serial.print((uint8_t)mensagem[i]);
 Serial.print(" ");
 }

 Serial.println();

 Serial.println("Mensagem criptografada (em bytes):");

 for (size_t i = 0; i < mensagemCriptografada.length(); i++) {
 Serial.print((uint8_t)mensagemCriptografada[i]);
 Serial.print(" ");
 }

 Serial.println();

 // Desencriptar a mensagem
 String mensagemDescriptografada = xorEncryptDecrypt(mensagemCriptografada);

 for (size_t i = 0; i < mensagemDescriptografada.length(); i++) {
 Serial.print((uint8_t)mensagemDescriptografada[i]);
 Serial.print(" ");
 }

 Serial.println();

 Serial.println("Mensagem descriptografada: " + mensagemDescriptografada);

 while (true);
}


Resultados

Tivemos como resultado a imagem abaixo:

Resultado visto no monitor serial. Feito pelo autor.

A primeira linha é a mensagem original; A segunda apresenta a mesma mensagem, só em na representação em bytes (caractere por caractere).

Em seguida, vemos a mensagem original, em formato de byte, posta acima da mensagem criptografada, também em formato de bytes. Lembrando que a segunda mensagem é o produto XOR entre a mensagem original e a frase secreta, byte a byte.

Por fim, passamos a mensagem criptografada mais uma vez pelo processo de XOR, resultando na mensagem original.


Considerações finais

Embora simples, este tutorial apresenta o básico por trás de qualquer algoritmo de criptografia: transformar uma mensagem legível em outra ilegível.

Esse recurso é bastante utilizado na indústria de IoT, principalmente quando o assunto é transmissão de dados via rádio.

Quer ver mais projetos legais como este? Dê uma olhada nos posts de nosso blog!


Sobre o autor


Guilherme Galanti

 


Eletrogate

28 de novembro de 2025

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!

Eletrogate Robô

Assine nossa newsletter e
receba  10% OFF  na sua
primeira compra!