Na criptografia, a cifra XOR simples é um tipo de cifra aditiva, 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). Esta operação às vezes é chamada de adição em módulo 2 (ou subtração, o que é idêntico). 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 A cadeia de texto "Wiki" ( em ASCII de 8 bits) pode ser criptografada com a chave de repetição da seguinte forma:
| = || style="border-top: 1px solid black" |
E inversamente, para a descriptografia:
| = || style="border-top: 1px solid black" |
Uso e segurança 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. 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 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.
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. + Tabela de Rastreamento da Cifra XORTexto ClaroChaveTexto Cifrado000011101110 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 ClaroChaveTexto Cifrado000010100111Se 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.
Exemplo de implementação Exemplo usando a linguagem de programação JavaScript.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. 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 Cifra de bloco Cifra de Vernam Cifra de Vigenère
Referências Notas
Citações
Fontes
Transcrição de uma palestra ministrada pelo Prof. Tutte na Universidade de Waterloo
Categoria:Cifras de fluxo Categoria:Cifras Categoria:Algoritmos