Pular para conteúdo

Cifra de Vigenère (Vigenère Cipher)

A cifra de Vigenère é uma cifra de substituição polialfabética que foi considerada uma das melhores cifras clássicas. Nomeada em homenagem a Blaise de Vigenère, um criptógrafo francês do século 16, ela melhora a simples substituição usando múltiplas cifras de César com diferentes valores de deslocamento baseados em uma palavra-chave.

Fundamento Matemático

A Tabela da Cifra (Tabula Recta)

A cifra de Vigenère usa uma tabela de alfabetos deslocados ciclicamente:

    A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z
  A A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z
  B C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   A
  C D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   A   B
  ...
  Z Z   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y

Fórmula de Criptografia

Dado: - Caractere de texto plano $P$ (posição no alfabeto, 0-25) - Caractere da palavra-chave $K$ (posição na palavra-chave, 0-25)

O caractere do texto cifrado $C$ é calculado como:

$$C = (P + K) \mod 26$$

Fórmula de Decifração

$$P = (C - K) \mod 26$$

Exemplo

Texto Plano: ATTACKATDAWN
Palavra-Chave: LEMON

Posição P L E M O L E M O L E M
0 A(0) +L(11) =L(11)
1 T(19) +E(4) =X(23)
2 T(19) +M(12) =G(7)
3 A(0) +O(14) =O(14)
4 C(2) +L(11) =N(13)
5 K(10) +E(4) =Q(14)
6 A(0) +M(12) =O(14)
7 T(19) +O(14) =D(3)
8 A(0) +L(11) =M(12)
9 D(3) +E(4) =H(7)
10 A(0) +M(12) =W(22)
11 W(22) +O(14) =G(6)

Texto Cifrado: LXGONQODMHWG

Implementação em Java

public class VigenereCipher {
    private static final int ALPHABET_SIZE = 26;

    /**
     * Cripta uma mensagem usando a cifra de Vigenère.
     * @param plaintext A mensagem original (apenas letras)
     * @param keyword A chave de criptografia
     * @return A mensagem criptografada
     */
    public static String encrypt(String plaintext, String keyword) {
        StringBuilder ciphertext = new StringBuilder();
        int[] keyPositions = getKeywordPositions(keyword);

        for (int i = 0; i < plaintext.length(); i++) {
            char c = plaintext.charAt(i);

            if (Character.isLetter(c)) {
                char base = Character.isUpperCase(c) ? 'A' : 'a';
                int position = c - base;
                int keyPosition = keyPositions[i % keyPositions.length];

                int encryptedPosition = (position + keyPosition) % ALPHABET_SIZE;
                ciphertext.append((char)(base + encryptedPosition));
            } else {
                ciphertext.append(c); // Preserva caracteres não alfabéticos
            }
        }

        return ciphertext.toString();
    }

    /**
     * Decifra uma mensagem criptografada com a cifra de Vigenère.
     * @param ciphertext A mensagem criptografada
     * @param keyword A chave de criptografia
     * @return A mensagem decifrada
     */
    public static String decrypt(String ciphertext, String keyword) {
        StringBuilder plaintext = new StringBuilder();
        int[] keyPositions = getKeywordPositions(keyword);

        for (int i = 0; i < ciphertext.length(); i++) {
            char c = ciphertext.charAt(i);

            if (Character.isLetter(c)) {
                char base = Character.isUpperCase(c) ? 'A' : 'a';
                int position = c - base;
                int keyPosition = keyPositions[i % keyPositions.length];

                int originalPosition = (position - keyPosition + ALPHABET_SIZE) % ALPHABET_SIZE;
                plaintext.append((char)(base + originalPosition));
            } else {
                plaintext.append(c); // Preserva caracteres não alfabéticos
            }
        }

        return plaintext.toString();
    }

    /**
     * Converte palavra-chave para array de posições (0-25).
     */
    private static int[] getKeywordPositions(String keyword) {
        int[] positions = new int[keyword.length()];
        for (int i = 0; i < keyword.length(); i++) {
            char c = Character.toUpperCase(keyword.charAt(i));
            positions[i] = c - 'A';
        }
        return positions;
    }

    public static void main(String[] args) {
        String message = "ATTACKATDAWN";
        String keyword = "LEMON";

        String encrypted = encrypt(message, keyword);
        System.out.println("Texto Plano:  " + message);
        System.out.println("Palavra-Chave:    " + keyword);
        System.out.println("Texto Cifrado: " + encrypted);

        String decrypted = decrypt(encrypted, keyword);
        System.out.println("Decifrado:  " + decrypted);
    }
}

Criptanálise: Exame de Kasiski e Índice de Coincidência

A cifra de Vigenère é vulnerável a criptanálise através de várias técnicas. A mais famosa é o exame de Kasiski.

Exame de Kasiski

Esta técnica explora padrões repetidos no texto cifrado que resultam de partes repetidas do texto plano alinhando-se com partes repetidas da palavra-chave.

Passos: 1. Encontre sequências repetidas no texto cifrado (pelo menos 3 caracteres) 2. Calcule as distâncias entre ocorrências 3. O maior divisor comum (MDC) dessas distâncias provavelmente revela o comprimento da chave 4. Uma vez conhecido o comprimento da chave, separe o texto cifrado em várias cifras de César e analise frequências

Exemplo de Análise Kasiski

Texto Cifrado: LXGONQODMHWG com análise de padrões repetidos...

Se encontrarmos "ON" aparecendo nas posições 3 e 10 (distância = 7), e outro padrão se repetir a cada 13 caracteres, o MDC pode ser 1. Isso sugere um comprimento de chave de 1 ou múltiplos dele.

Índice de Coincidência (IOC)

O IOC mede a probabilidade de que duas letras selecionadas aleatoriamente de um texto sejam idênticas. Para texto em inglês: - IOC esperado ≈ 0,067 (devido à distribuição de frequência das letras) - IOC de texto aleatório ≈ 0,038 (distribuição uniforme)

Calculando o IOC para diferentes comprimentos de chave, podemos determinar estatisticamente o comprimento da chave correta.

Análise de Segurança

Pontos Fortes e Fracos

Aspecto Avaliação
Espaço de Chave $26^n$ onde n é o comprimento da palavra-chave (maior que César)
Complexidade O(n) tempo, O(1) espaço
Vulnerabilidade Quebrável com Kasiski ou análise de frequência em grupos
Uso Moderno Apenas educacional - nunca para segurança real

Por Que Ainda é Ensinoada

Apesar de quebrável, a cifra de Vigenère demonstra conceitos importantes:

  1. Substituição Polialfabética: Usando múltiplos alfabetos para ocultar frequências de letras
  2. Impacto do Comprimento da Chave: Chaves mais longas fornecem melhor segurança (embora ainda não seguras)
  3. Significado Histórico: Usada por governos e militares por séculos
  4. Fundação para Cifras Modernas: Conceitos evoluíram para cifras de fluxo modernas

Contexto Histórico

A cifra de Vigenère foi usada extensivamente durante os séculos 16-19:

  • Marinha Francesa: Usada em comunicações navais
  • Comunicações Diplomáticas: Protegia segredos de estado
  • Primeira Guerra Mundial: Militares alemães usaram variantes (ex: ADFGVX)

Não foi quebrada até 1863 por Friedrich Kasiski, que publicou seu método de análise. Antes disso, era conhecida como a "cifra inexpugnável" (le chiffre indéchiffrable).

Variante Autokey

Uma variante mais segura chamada Autokey usa o próprio texto plano como parte do fluxo da chave:

  • Chave: LEMON
  • Texto Plano: ATTACKATDAWN
  • Chave estendida: LEMONATTAC... (palavra-chave + texto plano)

Isso torna a análise de frequência muito mais difícil, mas ainda vulnerável a ataques mais avançados.

Comparação com Criptografia Moderna

Característica Vigenère AES (Moderno)
Comprimento da Chave Variável (prático: 10-26 chars) 128, 192 ou 256 bits
Margem de Segurança Nenhuma - quebrável com suficiente texto cifrado Provavelmente seguro por décadas
Velocidade Muito rápida (operações simples) Rápida mas mais complexa
Implementação Fácil de implementar incorretamente Padronizada e testada

Referências

  1. Trappe, W., & Washington, L. C. (2006). Introduction to Cryptography with Coding Theory. Pearson.
  2. Stinson, D. R. (2005). Cryptography: Theory and Practice. CRC Press.
  3. Kahn, D. (1967). The Codebreakers: The Story of Secret Writing. Scribner.
  4. Friedman, W. F. (1920). "The Index of Coincidence and Its Application in Cryptography".