Na criptografia, a cifra XOR simples é um tipo de cifra aditiva,[1] um algoritmo de criptografia que opera de acordo com os seguintes princípios:

A 0 = A,
A A = 0,
A B = B A,
(A B) C = A (B C),
(B A) A = B 0 = B

Onde denota a operação de disjunção exclusiva (XOR).[2] Esta operação às vezes é chamada de adição em módulo 2 (ou subtração, o que é idêntico).[3] Com essa lógica, uma cadeia de texto pode ser criptografada aplicando o operador XOR bit a bit a cada caractere usando uma determinada chave. Para descriptografar a saída, basta reaplicar a função XOR com a chave para remover a cifra.

Exemplo

editar

A cadeia de texto "Wiki" (01010111 01101001 01101011 01101001 em ASCII de 8 bits) pode ser criptografada com a chave de repetição 11110011 da seguinte forma:

01010111 01101001 01101011 01101001
11110011 11110011 11110011 11110011
= 10100100 10011010 10011000 10011010

E inversamente, para a descriptografia:

10100100 10011010 10011000 10011010
11110011 11110011 11110011 11110011
= 01010111 01101001 01101011 01101001

Uso e segurança

editar

O operador XOR é extremamente comum como um componente em cifras mais complexas. Por si só, usando uma chave repetitiva constante, uma cifra XOR simples pode ser trivialmente quebrada usando a análise de frequência. Se o conteúdo de qualquer mensagem puder ser adivinhado ou conhecido de alguma outra forma, a chave poderá ser revelada. Seu principal mérito é que é simples de implementar e que a operação XOR é computacionalmente barata. Uma cifra XOR repetitiva simples (ou seja, usando a mesma chave para a operação XOR em todos os dados) é, portanto, às vezes usada para ocultar informações em casos em que nenhuma segurança específica é necessária. A cifra XOR é frequentemente usada em malware de computador para tornar a engenharia reversa mais difícil.

Se a chave for aleatória e for pelo menos tão longa quanto a mensagem, a cifra XOR será muito mais segura do que quando há repetição de chave dentro de uma mensagem.[4] Quando o fluxo de chave é gerado por um gerador de números pseudoaleatórios, o resultado é uma cifra de fluxo. Com uma chave que é verdadeiramente aleatória, o resultado é um one-time pad (cifra de uso único), que é teoricamente inquebrável.

O operador XOR em qualquer uma dessas cifras é vulnerável a um ataque de texto plano conhecido, uma vez que texto claro texto cifrado = chave. Também é trivial inverter bits arbitrários no texto claro descriptografado através da manipulação do texto cifrado. Isso é chamado de maleabilidade.

Utilidade na criptografia

editar

O principal motivo pelo qual o XOR é tão útil na criptografia é porque ele é "perfeitamente balanceado"; para uma determinada entrada de texto claro 0 ou 1, o resultado do texto cifrado tem a mesma probabilidade de ser 0 ou 1 para um bit de chave verdadeiramente aleatório.[5]

A tabela abaixo mostra todos os quatro pares possíveis de bits de texto claro e de chave. Fica claro que, se nada for conhecido sobre a chave ou o texto claro, nada poderá ser determinado apenas a partir do texto cifrado.[5]

Tabela de Rastreamento da Cifra XOR
Texto Claro Chave Texto Cifrado
0 0 0
0 1 1
1 0 1
1 1 0

Outras operações lógicas, como E (AND) ou OU (OR), não possuem esse mapeamento. Por exemplo, considere a tabela para a operação E abaixo:

Tabela de Rastreamento da Cifra E (AND)
Texto Claro Chave Texto Cifrado
0 0 0
0 1 0
1 0 0
1 1 1

Se o texto cifrado for 0, então há 2/3 de chance de que o texto claro também tenha sido 0. E se o texto cifrado for 1, então o texto claro teria obrigatoriamente de ser 1. Isso revela claramente informações sobre o texto original que a abordagem XOR não revela.[a]

Exemplo de implementação

editar

Exemplo usando a linguagem de programação JavaScript.[6]

function xor_Encrypt(inputString, key) {
  let encrypted_Hex = "";
  
  for (let i = 0; i < inputString.length; i++) {
    const plain_string = inputString.charCodeAt(i);
    const key_Char = key.charCodeAt(i % key.length);
    
    const xor_Result = plain_string ^ key_Char; // Realiza a operação XOR
    // Converte o resultado do XOR para uma string hexadecimal de dois dígitos
    // Preenche com '0' se for um único dígito (ex: 5 -> "05")
    let hex = xor_Result.toString(16);
    if (hex.length < 2) {
      hex = "0" + hex;
    }
    
    encrypted_Hex += hex;
  }
  return encrypted_Hex;
}

function xorDecrypt(hexInput, key) {
    let decrypted_String = '';
    // Passo 1: Converter a string hexInput em um array
    const bytes = [];
    
    // Itera através da string hexadecimal dois caracteres por vez
    for (let i = 0; i < hexInput.length; i += 2) {
        // Pega uma substring hexadecimal de dois caracteres (ex: "AB")
        const hexa_Byte = hexInput.slice(i, i + 2);
        // Converte a substring hexadecimal para um inteiro (ex: "AB" -> 171)
        bytes.push(parseInt(hexa_Byte, 16));
    }
    
    // Passo 2: Aplica o XOR em cada byte com a chave e converte de volta para caractere
    for (let i = 0; i < bytes.length; i++) {
        const byte_Value = bytes[i];
        const key_Char = key.charCodeAt(i % key.length);
        const xor_Result = byte_Value ^ key_Char; // Realiza a operação XOR
        // Converte o resultado do XOR de volta para um caractere
        decrypted_String += String.fromCharCode(xor_Result);
    }
    
    return decrypted_String;
}

Outro exemplo usando a linguagem de programação Python.[b]

from os import urandom


def generate_key(length: int) -> bytes:
    """Gera a chave de criptografia."""
    return urandom(length)


def xor_strings(s, t) -> bytes:
    """Concatena duas strings usando XOR."""
    if isinstance(s, str):
        # Strings de texto contêm caracteres únicos
        return "".join(chr(ord(a) ^ b) for a, b in zip(s, t)).encode("utf8")
    else:
        # Objetos bytes contêm valores inteiros no intervalo 0-255
        return bytes([a ^ b for a, b in zip(s, t)])


message = "Esta e uma mensagem secreta"
print("Mensagem:", message)

key = generate_key(len(message))
print("Chave:", key)

cipherText = xor_strings(message.encode("utf8"), key)
print("Texto Cifrado:", cipherText)
print("Descriptografado:", xor_strings(cipherText, key).decode("utf8"))

# Verificação
if xor_strings(cipherText, key).decode("utf8") == message:
    print("Teste unitário passou")
else:
    print("Teste unitário falhou")

Um exemplo mais curto usando a linguagem de programação R, baseado em um quebra-cabeça postado no Instagram pelo GCHQ.

secret_key <- c(0xc6, 0xb5, 0xca, 0x01) |> as.raw()

secret_message <- "I <3 Wikipedia" |>
  charToRaw() |>
  xor(secret_key) |>
  base64enc::base64encode()


secret_message_bytes <- secret_message |>
                        base64enc::base64decode()
xor(secret_message_bytes, secret_key) |> rawToChar()

Ver também

editar

Referências

editar

Notas

editar
  1. Existem 3 formas de obter um bit de saída (texto cifrado) 0 de uma operação E (AND):
    Texto Claro=0, chave=0;
    Texto Claro=0, chave=1;
    Texto Claro=1, chave=0.
    Portanto, se soubermos que o bit do texto cifrado é 0, há uma chance de 2/3 de que o bit do texto claro também tenha sido 0 para uma chave verdadeiramente aleatória. Para o XOR, existem exatamente 2 formas, então a chance é de 1/2 (ou seja, igualmente provável, de modo que não podemos aprender nada com essa informação).
  2. Isso foi inspirado por Richter 2012

Citações

editar
  1. Tutte 1998, p. 3
  2. Lewin 2012, pp. 14-19.
  3. Churchhouse 2002, p. 11
  4. Churchhouse 2002, p. 68
  5. a b Paar & Pelzl 2009, pp. 32–34.
  6. armasahar/XOR-Cipher, 26 de setembro de 2025 

Fontes

editar

📚 Artikel Terkait di Wikipedia

Dinâmica estrutural

finite element analysis software. DYSSOLVE: Dynamic System Solver - An encrypted-source, lightweight, free-of-charge software that can be used to solve

Blowfish

init(Cipher.ENCRYPT_MODE, key); byte[] encrypted = cipher.doFinal(text.getBytes()); String encryptedString = bytesToHex(encrypted); System.out.println("Encryptado

Threema

agosto de 2020). «Threema joins the ranks of E2EE chat apps that support encrypted video calls». ZDNet (em inglês). Consultado em 30 de outubro de 2020