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 criptosistema sin 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 denomina ataque 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 # -*- 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 # ATAQUE DE FUERZA BRUTA: # La función de descifrado es: Dk(Ci) = (Ci - K) mod n def descifrar(alfabeto,criptograma): for k in range(0,len(alfabeto)): texto_claro = '' for caracter in criptograma: texto_claro = texto_claro + str(alfabeto[(alfabeto.find(caracter) - int(k)) % len(alfabeto)]) print("[+] Desplazamiento:", k,";", len(alfabeto)-k, ";", texto_claro) def main(): # 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)) # MENÚ: # Se presenta el menú para que se seleccione una opción. 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 opción: ") 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(alfabeto,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:
Comentarios
Publicar un comentario