Proteja seus dados confidenciais com AES no Flutter

Tempo de leitura: 3 minutes

Neste artigo, mostrarei como criptografar seus dados confidenciais em seu aplicativo Flutter usando o AES (padrão de criptografia avançado).

O AES é baseado em um princípio de design conhecido como rede de substituição – permutação e é eficiente em software e hardware. É essencial para a segurança do governo, segurança cibernética e proteção de dados eletrônicos.

Segurança da AES

Os especialistas em segurança sustentam que o AES é seguro quando implementado corretamente. No entanto, as chaves de criptografia AES precisam ser protegidas. Até os sistemas criptográficos mais extensos podem ser vulneráveis se um hacker obtiver acesso à chave de criptografia.

Como funciona a criptografia de AES

Ao contrário de seu antecessor DES, o AES não usa uma rede Feistel. O AES é uma variante de Rijndael, com um tamanho de bloco fixo de 128 bits e um tamanho chave de 128, 192 ou 256 bits.

Aes inclui três cifras de bloco:

· AES-128

· AES-192

· AES-256

O AES-128 usa um comprimento de chave de 128 bits para criptografar e descriptografar um bloco de mensagens, enquanto o AES-192 usa um comprimento de chave de 192 bits e AES-256 um comprimento de chave de 256 bits para criptografar e descriptografar mensagens. Cada cifra criptografa e descriptografa dados em blocos de 128 bits usando chaves criptográficas de 128, 192 e 256 bits, respectivamente.

As cifras usam a mesma chave para criptografar e descriptografar, para que o remetente e o receptor devem conhecer e usar a mesma chave secreta.

Os tipos acima descritos usam rodadas diferentes no processo. Uma rodada consiste em várias etapas de processamento que incluem substituição, transporte e mistura do texto simples de entrada para transformá-lo na saída final do texto cifra.

· Chaves de 128 bits -> 10 rodadas

· Chaves de 192 bits -> 12 rodadas

· Chaves de 256 bits -> 14 rodadas

Existem 10 rodadas para chaves de 128 bits, 12 rodadas para chaves de 192 bits e 14 rodadas para chaves de 256 bits. Uma rodada consiste em várias etapas de processamento que incluem substituição, transposição e mistura do texto simples de entrada para transformá -lo na saída final do CipherText.

Diagrama básico de design da AES para referência
Diagrama básico de design da AES para referência

 

Vetor de inicialização (IV)

Um vetor de inicialização (ou iv) é usado para garantir que o mesmo valor criptografado várias vezes, mesmo com a mesma chave secreta, nem sempre resultará no mesmo valor criptografado. O IV deve ser não repetido e, para alguns modos, aleatório também. Esta é uma camada de segurança adicional.

Modos

O modo define qual algoritmo é usado para criptografar os dados. Alguns fornecem um nível mais alto de segurança/aleatoriedade que outros, mas a principal coisa aqui é usar o modo de criptografia que será usado para descriptografia do outro lado.

Os modos suportados são:

  • CBC AESMode.cbc
  • CFB-64 AESMode.cfb64
  • CTR AESMode.ctr
  • ECB AESMode.ecb
  • OFB-64/GCTR AESMode.ofb64Gctr
  • OFB-64 AESMode.ofb64
  • SIC AESMode.sic

 

Preenchimento

Quando chamamos de criptografia em nossa cifra (que foi inicializada com a chave de criptografia, o modo de criptografia e o vetor de inicialização), você notará que também estamos chamando o Pad sobre o valor que estamos criptografando primeiro. Isso remonta ao conceito de “tamanho do bloco” sobre o qual conversamos anteriormente. Como o AES é uma cifra de bloco que funciona em “blocos” de um comprimento predefinido, se o valor que estamos criptografando não for divisível de maneira limpa por esse comprimento, não funcionará. Chamada no valor adiciona bytes vazios ao final da sua string até que seja o número correto de bytes de comprimento.

 

Como usar

Usaremos a Biblioteca Encrypt: https://pub.dev/packages/encrypt

Versão atual 5.0.1 com 673 curtidas e 99% de popularidade

Adicione uma linha como essa ao pubSpec.yaml do seu pacote (e execute o Dart Pub Get):

dependencies:
  encrypt: ^5.0.1

Agora, no seu código de dardo, você pode usar:

import 'package:encrypt/encrypt.dart';
String encryption(String plainText) {
     
     final key = Key.fromBase64(ENCRYPTION_KEY);
     final iv = IV.fromBase64(ENCRYPTION_IV);

     final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));
     final encrypted = encrypter.encrypt(plainText, iv: iv);

 return encrypted.base64;   
}

String decryption(String plainText) {

   final key = Key.fromBase64(ENCRYPTION_KEY);
   final iv = IV.fromBase64(ENCRYPTION_IV);

   final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: 'PKCS7'));
   final decrypted = encrypter.decrypt(Encrypted.from64(plainText), iv: iv);

  return decrypted;   
 }

 

Modo e preenchimento são opcionais.

Além disso, você pode usar construtores como:

final key = Key.fromUtf8(ENCRYPTION_KEY);
final iv = IV.fromLength(16);