Quantcast
Channel: El blog de García Larragan y Cía
Viewing all articles
Browse latest Browse all 639

Criptografía (CCXLIII): Ataque de fuerza bruta al cifrado César

$
0
0

Continúo poniendo scripts de programación en python para automatizar tareas que tengan relación con la criptografía.

Ya puse una entrada con un script en python para cifrar y descifrar textos en claro y criptogramas, respectivamente, utilizando el cifrado César.  

Pues bien, ahora le toca el turno a un script para atacar un criptograma cifrado utilizando este criptosistemasin saber el desplazamiento empleado en el cifrado (típicamente 3, pero este cifrado se puede generalizar para cualquier desplazamiento - hasta 26, del 0 al 25 si se utiliza el alfabeto sin la letra "Ñ", o hasta 27, del 0 al 26, si se incluye la "Ñ").

El tipo de ataque a realizar mediante este script se denominaataque de fuerza bruta, y consiste en probar todas las posibles claves (en este caso, desplazamientos) hasta encontrar aquella que se utilizó en el cifrado, es decir, aquella cuya aplicación en el descifrado del criptograma produzca un texto en claro inteligible; lo que en este caso, recorrer el espacio de claves hasta encontrar la clave correcta, es posible realizar con el mínimo esfuerzo, incluso con lápiz y papel, porque el espacio de claves es minúsculo.

El script es el siguiente: 

#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ATAQUE DE FUERZA BRUTA AL CIFRADO CÉSAR:
#
# Ataque de fuerza bruta a un criptograma cifrado
# mediante el cifrado César probando todos los
# desplazamientos posibles.
#
# http://mikelgarcialarragan.blogspot.com/

import re
from unicodedata import normalize

# SELECCIÓN DE ALFABETO:
# Se solicita que se indique el alfabeto a emplear.
alfabeto = ""
while alfabeto == "":
    print ("")
    print ("*** SELECCIÓN DE ALFABETO ************************")
    print ('1. Alfabeto inglés  (26 caracteres, "Ñ" excluida).')
    print ('2. Alfabeto español (27 caracteres, "Ñ" incluida).')
    print ("")
    opcion = input("Por favor, seleccione una opcion: ")
    if opcion == "1":
        alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    elif opcion == "2":
        alfabeto = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"
    else:
        print ("*** ERROR: Opción no válida.")
print ("")
print ("[+] Alfabeto:", alfabeto)
print ("[+] Tamaño del alfabeto (n):", len(alfabeto))

# ATAQUE DE FUERZA BRUTA:
# La función de descifrado es: Dk(Ci) = (Ci - K) mod n
def descifrar(criptograma):
    for k in range(0,len(alfabeto)):
        texto_claro = ''
        i = 0
        for caracter in criptograma:
            texto_claro = texto_claro + str(alfabeto[int(alfabeto.find(caracter) - int(k)) % len(alfabeto)])
            i+=1
        print("[+] Desplazamiento:", k,";", len(alfabeto)-k, ";", texto_claro)
        k+=1

# MENÚ:
# Se presenta el menú para que se seleccione una opción.
def main():
    salir = False
    while not salir:
        print ("")
        print ("*** MENÚ *****************************************")
        print ("1. Ataque de fuerza bruta al cifrado César.")
        print ("2. Salir.")
        print ("")
        opcion = input("Por favor, seleccione una opcion: ")
        if opcion == "1":
            print ("")
            print ("--- ATAQUE DE FUERZA BRUTA:")
            # Se introduce el criptograma. Se convierten los caracteres a mayúsculas y
            # se eliminan los espacios, las tildes, diéresis, etc.
            criptograma = "*"
            while not criptograma.isalpha():
                criptograma = input('Criptograma a atacar: ').upper()
                criptograma = criptograma.replace('','')
                criptograma = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
                                      r"\1", normalize("NFD", criptograma), 0, re.I)
                criptograma = normalize("NFC", criptograma)
                if criptograma.isalpha():
                    print ("[+] Criptograma a atacar:", criptograma)
                    descifrar(criptograma)
                else:
                    print ("*** ERROR: El criptograma a atacar sólo debe contener caracteres alfabéticos.")
        elif opcion == "2":
            print ("*** FIN ******************************************")
            salir = True
        else:
            print ("*** ERROR: Opción no válida.")
	
if __name__ == '__main__':
    main()

Lo ejecuto:


Viewing all articles
Browse latest Browse all 639

Trending Articles