En criptografía, el cifrado César, también conocido como cifrado por desplazamiento, es una de las técnicas de cifrado más simples y más usadas. Es un tipo de cifrado por sustitución en el que una letra en el texto original es reemplazada por otra letra que se encuentra un número fijo de posiciones más adelante en el alfabeto. wikipedia



Por ejemplo, con un desplazamiento de 3, la A sería sustituida por la D (situada 3 lugares a la derecha de la A), la B sería reemplazada por la E, etc. Este método debe su nombre al dictador romano Julio César, quien lo usaba para comunicarse con sus generales.

Cifrado

Para implementar el cifrado César en Ruby tomamos el texto claro y a cada uno de sus caracteres le sumamos el desplazamiento.

#!/usr/bin/ruby

texto_claro = "Este es el MENSAJE SECRETO"
desplazamiento = 3

caracteres_cifrados = []
texto_claro.each_char do |c|
  caracteres_cifrados << (c.ord + desplazamiento).chr
end

texto_cifrado = caracteres_cifrados.join('').to_s

p texto_cifrado

Descifrado

El proceso de descifrado se realiza restándole el desplazamiento a cada uno de los caracteres del texto cifrado.

#!/usr/bin/ruby

texto_cifrado = "Hvwh#hv#ho#PHQVDMH#VHFUHWR"
desplazamiento = 3

caracteres_descifrados = []
texto_cifrado.each_char do |c|
  caracteres_descifrados << (c.ord - desplazamiento).chr
end

texto_descifrado = caracteres_descifrados.join('').to_s

p texto_descifrado

Ataques

Existen dos tipos de ataques para descifrar un mensaje que ha sido encriptado con el cifrado César:

Fuerza bruta

Este ataque consiste en probar uno a uno todos los desplazamientos posibles hasta encontrar un mensaje coherente.

#!/usr/bin/ruby

texto_cifrado = "Hvwh#hv#ho#PHQVDMH#VHFUHWR"
desplazamiento_maximo = 36

desplazamiento_maximo.times do |i|
  caracteres_descifrados = []
  texto_cifrado.each_char { |c| caracteres_descifrados << (c.ord - i).chr }
  texto_descifrado = caracteres_descifrados.join('').to_s
  p "Desplazamiento: #{i} -> #{texto_descifrado}"
end

Análisis de frecuencia

En este ataque se identifican las letras más comunes en el mensaje cifrado, y conociendo la distribución de letras del idioma original del mensaje original, se puede determinar fácilmente el valor del desplazamiento. Por ejemplo, en español, las letras más frecuentes son la E y la A, mientras que las menos frecuentes son la K y la W.

#!/usr/bin/ruby

texto_cifrado = "Hvwh#hv#ho#PHQVDMH#VHFUHWR"

frecuencias = {}

texto_cifrado.each_char do |c|
  frecuencias[c] = 0 unless frecuencias.include? c
  frecuencias[c] += 1
end

caracteres_mas_frecuentes = frecuencias.sort_by{|k,v| v}.reverse.take(3).to_h
caracteres_mas_frecuentes.each do |f|
  desplazamiento = f[0].ord - "E".ord
  puts "\nSuponiendo #{f[0]} -> E, desplazamiento: #{desplazamiento}"
  caracteres_descifrados = []
  texto_cifrado.each_char { |c| caracteres_descifrados << (c.ord - desplazamiento).chr }
  texto_descifrado = caracteres_descifrados.join('').to_s
  puts texto_descifrado
end