Inicio Linux & Systems Networks & Infrastructure Cybersecurity Cloud & DevOps SIEM & Monitoring DFIR & Threat Intel Development & Other Todas las categorias Herramientas Proyectos Sobre

Critpografía basica: Cifrado por sustitución

Read in English
Critpografía basica: Cifrado por sustitución

Tabla de contenidos

Los cifrados por sustitución son una de las familias más antiguas de algoritmos criptográficos. Su principio es sencillo: cada letra (o grupo de letras) del texto original se reemplaza por otra letra según una regla definida. Aunque estos cifrados son triviales de romper con técnicas modernas, su estudio es fundamental para comprender los principios de la criptografía y la evolución histórica de las comunicaciones seguras. En esta primera parte cubriremos tres cifrados clásicos: César, Polybios y ROT13.

Cifrado César

El cifrado César es el cifrado por sustitución más conocido de la historia. Utilizado por Julio César para comunicarse con sus generales, consiste en desplazar cada letra del alfabeto un número fijo de posiciones. Si el desplazamiento es 3 (el que usaba César), la A se convierte en D, la B en E, y así sucesivamente:

text
Alfabeto original:  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
Desplazamiento +3:  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 C

Texto original:  ATACAR AL AMANECER
Texto cifrado:   DWDFDU DO DPDQHFHU

La fórmula matemática del cifrado César es:

text
Cifrado:    C(x) = (x + k) mod 26
Descifrado: D(x) = (x - k) mod 26

Donde:
  x = posición de la letra (A=0, B=1, ..., Z=25)
  k = clave (desplazamiento)

Implementación en Python:

python
def cifrado_cesar(texto, desplazamiento, descifrar=False):
    """Cifrado/descifrado César."""
    if descifrar:
        desplazamiento = -desplazamiento
    resultado = []
    for char in texto:
        if char.isalpha():
            base = ord('A') if char.isupper() else ord('a')
            resultado.append(chr((ord(char) - base + desplazamiento) % 26 + base))
        else:
            resultado.append(char)
    return ''.join(resultado)

# Cifrar
texto = "ATACAR AL AMANECER"
cifrado = cifrado_cesar(texto, 3)
print(f"Cifrado: {cifrado}")  # DWDFDU DO DPDQHFHU

# Descifrar
descifrado = cifrado_cesar(cifrado, 3, descifrar=True)
print(f"Descifrado: {descifrado}")  # ATACAR AL AMANECER

Criptoanálisis del cifrado César

El cifrado César es extremadamente débil porque solo tiene 25 claves posibles (desplazamientos del 1 al 25). Un ataque por fuerza bruta es trivial:

python
def fuerza_bruta_cesar(texto_cifrado):
    """Probar todas las claves posibles."""
    print("=== Fuerza bruta César ===")
    for k in range(1, 26):
        descifrado = cifrado_cesar(texto_cifrado, k, descifrar=True)
        print(f"  Clave {k:2d}: {descifrado}")

fuerza_bruta_cesar("DWDFDU DO DPDQHFHU")

También se puede romper mediante análisis de frecuencia: en español, la letra más frecuente es la E (~13.7%). Si la letra más frecuente en el texto cifrado es la H, el desplazamiento probable es 3 (H - E = 3).

Cifrado de Polybios

El cuadrado de Polybios fue inventado por el historiador griego Polybios en el siglo II a.C. Convierte cada letra en un par de coordenadas numéricas usando una cuadrícula de 5x5:

text
Cuadrado de Polybios (sin Ñ, I=J):

    1  2  3  4  5
1   A  B  C  D  E
2   F  G  H  I  K
3   L  M  N  O  P
4   Q  R  S  T  U
5   V  W  X  Y  Z

Ejemplo:
  H = fila 2, columna 3 = 23
  O = fila 3, columna 4 = 34
  L = fila 3, columna 1 = 31
  A = fila 1, columna 1 = 11

  HOLA = 23 34 31 11

Implementación en Python:

python
def polybios_cifrar(texto):
    """Cifrar texto usando el cuadrado de Polybios."""
    cuadrado = "ABCDEFGHIKLMNOPQRSTUVWXYZ"  # Sin J (I=J)
    resultado = []
    for char in texto.upper():
        if char == 'J':
            char = 'I'
        if char in cuadrado:
            idx = cuadrado.index(char)
            fila = idx // 5 + 1
            col = idx % 5 + 1
            resultado.append(f"{fila}{col}")
        elif char == ' ':
            resultado.append(' ')
    return ' '.join(resultado) if ' ' not in resultado else ''.join(resultado)

def polybios_descifrar(cifrado):
    """Descifrar texto cifrado con Polybios."""
    cuadrado = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
    numeros = cifrado.replace(' ', '')
    resultado = []
    for i in range(0, len(numeros), 2):
        fila = int(numeros[i]) - 1
        col = int(numeros[i+1]) - 1
        resultado.append(cuadrado[fila * 5 + col])
    return ''.join(resultado)

cifrado = polybios_cifrar("HOLA MUNDO")
print(f"Cifrado: {cifrado}")

descifrado = polybios_descifrar("2334311132453334")
print(f"Descifrado: {descifrado}")

El cifrado de Polybios es interesante históricamente porque convierte letras en números, lo que facilitaba la transmisión por señales (antorchas, banderas). Es la base de cifrados más complejos como ADFGVX, utilizado por el ejército alemán en la Primera Guerra Mundial.

ROT13

ROT13 es un caso particular del cifrado César con desplazamiento de 13 posiciones. Su propiedad más notable es que es involutivo: aplicar ROT13 dos veces devuelve el texto original, ya que 13 + 13 = 26 (la longitud del alfabeto):

text
Original: 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
ROT13:    N O P Q R S T U V W X Y Z A B C D E F G H I J K L M

Texto:    SECRETO
ROT13:    FRPERGB
ROT13x2:  SECRETO  (vuelve al original)
python
import codecs

# ROT13 en Python (método estándar)
texto = "SECRETO"
cifrado = codecs.encode(texto, 'rot_13')
print(f"ROT13: {cifrado}")  # FRPERGB

# Descifrar es aplicar ROT13 de nuevo
descifrado = codecs.encode(cifrado, 'rot_13')
print(f"Original: {descifrado}")  # SECRETO

# También funciona con la función César que ya definimos
rot13 = cifrado_cesar("SECRETO", 13)
print(f"ROT13: {rot13}")  # FRPERGB

ROT13 no se considera un cifrado de seguridad — es una ofuscación. Se usa históricamente en foros de internet para ocultar spoilers, respuestas a acertijos o contenido que el lector debe elegir conscientemente descifrar. También aparece frecuentemente en retos de CTF (Capture The Flag) como paso inicial de decodificación.

Comparativa de los tres cifrados

text
Cifrado     | Claves posibles | Tipo           | Resistencia
------------|-----------------|----------------|------------------
César       | 25              | Monoalfabético | Fuerza bruta trivial
Polybios    | 1 (fijo)        | Fraccional     | Sin clave, solo ofuscación
ROT13       | 1 (fijo, k=13)  | Monoalfabético | Sin seguridad real

Estos tres cifrados comparten una debilidad fundamental: son monoalfabéticos, lo que significa que cada letra del texto original siempre se sustituye por la misma letra en el texto cifrado. Esto los hace vulnerables al análisis de frecuencia. En la segunda parte de esta serie exploraremos cifrados polialfabéticos como Vigenère y Playfair, que resuelven parcialmente esta debilidad.

:wq!

Comentarios