Pular para conteúdo

Criptografia Simétrica (Symmetric Encryption)

A criptografia simétrica usa uma única chave secreta compartilhada tanto para criptografia quanto para descriptografia. É a forma mais eficiente de criptografia, tornando-se ideal para criptografar grandes quantidades de dados em repouso ou em trânsito quando a troca segura de chaves pode ser estabelecida previamente.

Fundamento Matemático

Operação Básica

Dado: - Texto plano $M$ (mensagem a ser criptografada) - Chave secreta $K$ - Função de criptografia $E_K(\cdot)$ - Função de descriptografia $D_K(\cdot)$

O processo de criptografia é: $$C = E_K(M)$$

O processo de descriptografia é: $$M = D_K(C)$$

Onde $C$ é o texto cifrado.

Requisito de Segurança

Para que um cifra seja seguro, ele deve satisfazer: $$D_K(E_K(M)) = M \quad \text{para todo } M$$

E idealmente: $$D_{K'}(E_K(M)) \neq M \quad \text{para qualquer } K' \neq K$$

AES (Advanced Encryption Standard)

O AES é o algoritmo de criptografia simétrica mais amplamente usado hoje, adotado pelo NIST em 2001. Ele substituiu o antigo Data Encryption Standard (DES).

Tamanhos de Chave

Variante Tamanho do Bloco Tamanho da Chave Nível de Segurança
AES-128 128 bits 128 bits ~128-bit security
AES-192 128 bits 192 bits ~192-bit security
AES-256 128 bits 256 bits ~256-bit security

Estrutura: Rede de Substituição-Permutação (SPN)

O AES opera em uma matriz de estado 4×4 de bytes e realiza as seguintes operações em cada rodada:

1. Rodada Inicial

  • AddRoundKey: XOR o estado com a chave da rodada

2. Rodadas Principais (9 para AES-128, 11 para AES-256)

Cada rodada principal consiste de: - SubBytes: Substituição não-linear usando S-box - ShiftRows: Deslocamento cíclico das linhas na matriz de estado - MixColumns: Mistura linear das colunas - AddRoundKey: XOR com chave da rodada

3. Rodada Final

Mesma que as rodadas principais, mas sem MixColumns

Representação da Matriz de Estado do AES

Estado (bloco de 128 bits):
+--------+--------+--------+--------+
| s00    | s01    | s02    | s03    |
+--------+--------+--------+--------+
| s10    | s11    | s12    | s13    |
+--------+--------+--------+--------+
| s20    | s21    | s22    | s23    |
+--------+--------+--------+--------+
| s30    | s31    | s32    | s33    |
+--------+--------+--------+--------+

Cada byte de estado é 8 bits, total = 4 × 4 × 8 = 128 bits

S-Box (Caixa de Substituição)

A S-box fornece não-linearidade. Ela é derivada do inverso multiplicativo em GF(2^8):

$$S[x] = \text{Inverse}(x)^{-1} \oplus \text{Constante}$$

Onde a constante é 0x63 para propriedades de uniformidade diferencial.

Implementação em Java

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;

public class CriptografiaSimetrica {

    private static final String ALGORITMO = "AES/GCM/NoPadding";
    private static final int IV_LENGTH = 12; // 96 bits para GCM

    /**
     * Gera uma nova chave AES-256.
     */
    public static SecretKey gerarChave() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256); // Tamanho da chave em bits
        return keyGen.generateKey();
    }

    /**
     * Criptografa dados usando AES-GCM.
     * @param textoPlano Os dados a serem criptografados
     * @param chave A chave secreta
     * @return Texto cifrado codificado em Base64 com IV prependido
     */
    public static String criptografar(String textoPlano, SecretKey chave) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITMO);

        // Gerar vetor de inicialização (IV) aleatório
        byte[] iv = new byte[IV_LENGTH];
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(iv);

        GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv);
        cipher.init(Cipher.ENCRYPT_MODE, chave, parameterSpec);

        byte[] textoCifrado = cipher.doFinal(textoPlano.getBytes());

        // Combinar IV e texto cifrado, depois codificar
        byte[] combinado = new byte[iv.length + textoCifrado.length];
        System.arraycopy(iv, 0, combinado, 0, iv.length);
        System.arraycopy(textoCifrado, 0, combinado, iv.length, textoCifrado.length);

        return Base64.getEncoder().encodeToString(combinado);
    }

    /**
     * Descriptografa dados criptografados com AES-GCM.
     */
    public static String descriptografar(String textoCifradoCodificado, SecretKey chave) throws Exception {
        // Decodificar e separar IV do texto cifrado
        byte[] combinado = Base64.getDecoder().decode(textoCifradoCodificado);
        byte[] iv = new byte[IV_LENGTH];
        byte[] bytesTextoCifrado = new byte[combinado.length - IV_LENGTH];

        System.arraycopy(combinado, 0, iv, 0, IV_LENGTH);
        System.arraycopy(combinado, IV_LENGTH, bytesTextoCifrado, 0, bytesTextoCifrado.length);

        Cipher cipher = Cipher.getInstance(ALGORITMO);
        GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv);
        cipher.init(Cipher.DECRYPT_MODE, chave, parameterSpec);

        byte[] bytesTextoPlano = cipher.doFinal(bytesTextoCifrado);
        return new String(bytesTextoPlano);
    }

    public static void main(String[] args) throws Exception {
        SecretKey chave = gerarChave();
        String mensagem = "Mensagem secreta para criptografar";

        // Criptografar
        String criptografado = criptografar(mensagem, chave);
        System.out.println("Criptografado: " + criptografado);

        // Descriptografar
        String descriptografado = descriptografar(criptografado, chave);
        System.out.println("Descriptografado: " + descriptografado);
    }
}

Usando a Classe Cipher do Java (Exemplo Simples)

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;

public class AESSimples {

    public static String criptografar(String textoPlano, byte[] bytesChave) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(bytesChave, "AES");

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        return Base64.getEncoder().encodeToString(cipher.doFinal(textoPlano.getBytes()));
    }

    public static String descriptografar(String textoCifradoCodificado, byte[] bytesChave) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(bytesChave, "AES");

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);

        return new String(cipher.doFinal(Base64.getDecoder().decode(textoCifradoCodificado)));
    }

    public static byte[] gerarChave() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256);
        SecretKey chave = keyGen.generateKey();
        return chave.getEncoded();
    }
}

Modos de Operação

ECB (Electronic Codebook) - NÃO RECOMENDADO

Cada bloco é criptografado independentemente. Blocos de texto plano idênticos produzem blocos de texto cifrado idênticos, vazando padrões:

Texto Plano: [AAAA][BBBB][CCCC]
Texto Cifrado: [XXXX][YYYY][ZZZZ]  // Padrão visível!

CBC (Cipher Block Chaining)

Cada bloco de texto plano é XORado com o bloco de texto cifrado anterior antes da criptografia. Requer um vetor de inicialização (IV):

$$C_i = E_K(P_i \oplus C_{i-1})$$

Com $C_0 = IV$.

Segurança: Esconde padrões, mas erros propagam para o bloco seguinte.

GCM (Galois/Counter Mode) - RECOMENDADO

Fornece tanto confidencialidade quanto autenticação: - Usa modo Counter para criptografia - Fornece criptografia autenticada via multiplicação de campo Galois - Escolha mais segura moderna

Gerenciamento de Chaves

Funções de Derivação de Chave (KDFs)

Convertem senhas ou chaves de baixa entropia em chaves criptográficas:

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public class DerivacaoChave {

    public static byte[] derivarChave(char[] senha, byte[] salt) throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");

        PBEKeySpec spec = new PBEKeySpec(senha, salt, 65536, 256); // 65k iterações

        return factory.generateSecret(spec).getEncoded();
    }
}

Melhores Práticas para Gerenciamento de Chaves

  1. Nunca codifique chaves no código fonte
  2. Use armazenamento seguro: HashiCorp Vault, AWS KMS, Azure Key Vault
  3. Rode chaves regularmente
  4. Use chaves diferentes para diferentes propósitos (criptografia vs assinatura)
  5. Implemente controles de acesso ao armazenamento de chaves

Análise de Segurança

Pontos Fortes e Fracos

Aspecto Avaliação
Velocidade Muito rápida, adequada para grandes dados
Tamanho da Chave 128-256 bits (segurança computacional)
Implementação Padrões bem avaliados (AES)
Vulnerabilidade Requer troca segura de chaves

Por que o AES é Seguro

  1. Espaço de Chave Grande: $2^{256}$ chaves possíveis para AES-256
  2. Resistência a Ataques Conhecidos: Nenhum ataque prático mais rápido que força bruta
  3. Padronização: Análise extensiva por criptógrafos em todo o mundo
  4. Aceleração de Hardware: Disponível na maioria dos processadores modernos

DES está Obsoleto

O antigo Data Encryption Standard (DES) usa apenas chaves de 56 bits: - Espaço de chave: $2^{56} \approx 7,2 \times 10^{16}$ combinações - Quebrado desde os anos 1990 - Nunca use DES para novas aplicações

Comparação com Criptografia Assimétrica

Característica Simétrica (AES) Assimétrica (RSA/ECC)
Tamanho da Chave 128-256 bits 2048-4096 bits
Velocidade Muito rápida (~$10^3\times$ mais rápido) Mais lento
Uso Criptografar dados Troca de chaves, assinaturas
Troca de Chave Requer segredo pré-compartilhado Troca segura embutida

Criptografia Híbrida (TLS/SSL)

Protocolos modernos combinam ambas as abordagens:

1. Cliente e Servidor realizam troca de chaves Diffie-Hellman
2. Estabelecer chave simétrica compartilhada
3. Usar AES para criptografar a transferência real de dados
4. Assinar com RSA/ECC para autenticação

Isso fornece a eficiência da criptografia simétrica com a troca segura de chaves da criptografia assimétrica.

Referências

  1. NIST FIPS 197: Advanced Encryption Standard (AES)
  2. Daemen, J., & Rijmen, V. (2002). The Design of Rijndael. Springer.
  3. Ferguson, N., Schneier, B., & Kohno, T. (2010). Cryptographic Engineering. MIT Press.
  4. Stinson, D. R. (2005). Cryptography: Theory and Practice. CRC Press.