Segurança de dados com AES

Segurança de dados

A segurança é algo essêncial em muitos projetos, principalmente nos conectados à Internet. Desde esconder senhas ou mensagens para que ninguém além do destino possa ler, a segurança faz parte do nosso cotidiano e iremos aprender a implementa-la nos Microcontroladores. Aprenderemos usar a criptografia AES (Advanced Encryption Standard) com foco em apenas sobre sigilo do dado, o download dela estará ao fim do tutorial. Esta biblioteca para criptografia com AES, funciona tanto para Arduino, quanto para ESP8266 ou ESP32.

 

 

Um pouco sobre segurança

Antes de entrar em detalhes sobre o AES, um resumo sobre a segurança de dados.

 

-Codificação

A codificação é possivelmente o método mais simples e antigo, trata-se da troca de uma linguagem, para outro padrão. É necessário conhecer os caracteres codificados para poder decodificar. O objetivo da codificação não é tornar a mensagem secreta. Exemplo: Morse(Fig 1), que converte os caracteres para pulsos elétricos, sons, luzes, etc.

-Criptografia simétrica

A criptografia simétrica faz o uso de uma chave privada que deve ser mantida em segredo, já que é usada tanto para encriptação, quanto para desencriptação. Esta é mais simples e leve que a criptografia assimétrica. Exemplo: AES, DES.

-Criptografia assimétrica

A criptografia assimétrica faz o uso de duas chaves, uma pública e outra privada. A pública pode ser usada para encriptação e a privada para desencriptação. Esta é mais pesada e lenta. Exemplo: RSA.

O uso delas é bem diferente e logo, a comparação direta não faz sentido. Por exemplo, a assimétrica permite autenticidade dos dados e pode garantir que o dado recebido é de uma pessoa autorizada e não de alguém re-enviando o dado.

 

 

-Hash

Hash é um algoritmo de uma via, ou seja, é irreversível. É muito usado com senhas da seguinte forma: Primeiramente é gerado um Hash da senha e este, será apenas comparado ao Hash armazenado no destino. Caso os Hash's sejam iguais, logo a senha é igual. Exemplo: MD5, SHA-1.

Clique AQUI para mais informações sobre Hash.

 

-AES

AES (Advanced Encryption Standard), é uma criptografia de blocos com chave simétrica (cifra de bloco) e será usado AES-128 no exemplo deste tutorial. AES trabalha com o sistema de blocos de 16 Bytes. É possível utilizar valores de entrada menores sem problemas, mas maiores será necessário dividir em blocos de 16B.

 

 

Imagine que você use dois micro controladores para transmissão de mensagens (Exemplo: Whatsapp, Facebook...), muito provavelmente você deseja que ninguém consiga ler as mensagens, isto pode ser feito com a encriptação, que irá cifrar (embaralhar) a mensagem e deixa-la ilegível para qualquer pessoa sem a chave, garantindo que apenas as pessoas com a chave, consigam ler.

Também pode ser usada para protocolos de comunicação entre dispositivos Wireless ou Wired, para preservar a integridade do mesmo e evitar "curiosos de plantão".


Mãos à obra

Código do projeto

#include <AES.h>//Biblioteca do AES.

AES aes;//Cria a classe aes.
byte key[16], out[16], inp[32];//Cria arrays (vetores) para a chave, input e output de dados.
const char pass[] = "abc";//Define a chave usada, neste exemplo usamos AES128, então precisa ser <= 16 Bytes.


void setup()
{
   Serial.begin(115200);//Habilita a serial.
   Serial.println();//Limpa o monitor.

   enc128("vida de silicio", 1);//Faz a função de encriptação e retorna o HEX encriptado.
}

void loop()
{

}


void enc128(const char txt[], bool db)//Argumentos: (texto e debug)
{
   if (strlen(pass) > 16)//Verifica se a chave tem o tamanho limite de 16 caracteres.
   {
      if (db == true)
      {
         Serial.println("Chave para AES128 <= 16 Bytes");
      }
      return;//Se a chave for maior, irá sair da função.
   }

   if (strlen(txt) > 16)//Verifica se o texto tem o tamanho limite de 16 caracteres.
   {
      if (db == true)
      {
         Serial.println("Frase/numero para AES <= 16 Bytes / bloco");
      }
      return;//Se o texto for maior, irá sair da função.
   }

   for (byte i = 0; i < strlen(pass); i++)//Adiciona a chave(pass) na array key.
   {
      key[i] = pass[i];
   }

   for (byte i = 0; i < strlen(txt); i++)//Adiciona o texto na array input.
   {
      inp[i] = txt[i];
   }

   //Adiciona a chave ao algoritimo.
   if (aes.set_key(key, 16) != 0)//Verifica se a chave esta correta, caso nao, sairá da função.
   {
      if (db == true)
      {
         Serial.println("Erro ao configurar chave");
      }
      return;//Sai da função
   }

   //Faz a encriptação da array INPUT e retorna o HEXA na array OUTPUT.
   if (aes.encrypt(inp, out) != 0)//Verifica se a encriptação esta correta, se não, sairá da função.
   {
      if (db == true)
      {
         Serial.println("Erro ao encriptar");
      }
      return;//Sai da função
   }

   if (db == true)//Se o debug estiver on (1), irá mostrar o HEXA no serial monitor.
   {
      for (byte i = 0; i < 16; i++)
      {
         Serial.print(out[i], HEX);
         Serial.print(" ");
      }
      Serial.println();
   }

   aes.clean();//Limpa a chave e residuos sensiveis da encriptação.
}

Entendendo a fundo

Software

A função que desenvolvemos enc128() torna o uso muito simples, mas você deve estudar mais sobre o AES e a biblioteca usada para entender melhor o funcionamento. Aqui será mostrado apenas a encriptação, mas também é possível fazer a desencriptação da mesma forma, este será o desafio de vocês para aprendizado.


 

-Variaveis usadas

byte key[16], out[16], inp[32];

Criamos os vetores (Arrays) para alocar a CHAVE e mensagens de INPUT e OUTPUT do buffer AES.

 

-Definindo a chave

char pass[] = "abc";

Definimos a Key (chave) da nossa criptografia. Deve ter no mínimo 1 caractere, e no máximo 16 (AES 128).  0 < Key <= 16. Aqui usamos "abc", mas é aconselhado o uso de letras e números aleatórios.

Você deve usar chaves grandes e aleatórias. Sem isso, seu sistema estará em grandes riscos. Usamos uma chave simples para fácil entendimento.

 

-Função enc128()

enc128("vida de silicio", 1);

enc128(texto, debug);

A função criada para encriptação dos dados torna o processo bem fácil. Os parâmetros necessários para ela é o texto que deseja encriptar, e em seguida, o debug, que mostra no serial monitor possíveis erros e por fim, o HEX da encriptação.

O texto para encriptação deve estar entre aspas e ser menor que 17 caracteres (bytes). 0 < texto <= 16.

O debug é ativado com 1 e desativado com 0, aconselhamos a sempre usar 1 para caso aconteça erros.

 

-Função AES::set_key()

aes.set_key(key, 16);

Com esta função, é adicionado a nossa chave ao sistema de criptografia interno.

Obs: A chave para AES é 128/192/256b, porém, para ser didático, foi usado apenas 3 caracteres. Tome cuidado ao usar chaves de outros tamanhos, alguns lugares não aceitam!

 

-Função AES::encrypt()

aes.encrypt(inp, out);

Esta função, faz a encriptação dos dados que estão dentro do vetor INP, e retorna os valores dentro do vetor OUT.


Colocando para funcionar

Ao testar o código que foi mostrado aqui, será gerado exatamente este código em hexadecimal "4A 38 3A 94 FC FB C4 C6 E1 4F D2 5D 34 7B B5 80", este código hexadecimal é a nossa mensagem encriptada. Encontrei um site bem legal que faz a encriptação e desencriptação dos dados AES, usarei ele.

Coloquei a nossa chave "abc" e o código hexadecimal gerado pelo micro controlador. Após clicar para desencriptar, é mostrado a mensagem original, e como podemos ver, funcionou.

o AES permite vários métodos de encriptação, a mais simples é a ECB, a biblioteca usada no tutorial também permite a CBC que é mais segura, porém mais complicada.

Clique AQUI para ir ao site.


Desafio

O desafio para vocês é que façam a desencriptação de um código hex, estudem sobre o assunto e veja as funções da biblioteca! Vocês podem desencriptar o próprio hex gerado da sua encriptação, ou usar o site indicado anteriormente para obter um hex e ver se a desencriptação funciona. Lembrando que esta biblioteca funciona para Arduino, ESP8266 e ESP32.

Download da biblioteca: https://github.com/spaniakos/AES

 

Fechamento

A segurança é extremamente importante em IoT e nao deve ser esquecida. Sempre adicione caso seja necessário em seu projeto, e principalmente em produtos comerciais. Tem dúvidas? sugestões? críticas? Comente abaixo!