¿Puedes descifrarme?

Iniciado por 000000 000000, Abril 03, 2020, 09:45:42 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Abril 03, 2020, 09:45:42 AM Ultima modificación: Abril 04, 2020, 11:49:48 AM por Miguel Alonso
Hola  ;)

Hoy traigo algo bastante especial, estos días he estado programando un cifrador.
Dato: Un cifrado no puede descifrase sabiendo los datos del cifrado de lo contrario es una codificación me explico:

El binario una de las codificaciones más famosas del mundo sabiendo el metodo de codificación podríamos descifrarlo. Pero con AES por ejemplo uno de los cifrados más conocidos aunque conozcamos el metodo de cifrado no podríamos descifralo por esa forma. Sabiendo esto continuemos.

He creado un cifrado, en python3 No tienes permitido ver los links. Registrarse o Entrar a mi cuenta que tiene una clave y (o al menos se intento)
no se podría descifrar sin romper la clave. Quería proponer intentar descifrar un mensaje para ver si es seguro. De esta forma la comunidad gana porque se puede jugar con el que a mi parecer es interesante y yo gano por los bugs. Win & Win.

Captura del proyecto:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


(ADVERTENCIA: Solo soporta letras minusculas y números.)
Texto cifrado: 309224446557488409754066854545005782200040975244112

Si lo conseguís ponedlo abajo en los comentarios.  :P

Saludos  :)

Abril 04, 2020, 11:44:57 AM #1 Ultima modificación: Abril 04, 2020, 11:51:43 AM por Miguel Alonso
Hola.
Un amigo dan884075 que no tiene cuenta en underc0de rompió el cifrado por una vulnerabilidad que explicará el, estoy parcheando la versión la publicaré próximamente. Aquí dejo sus palabras:

El texto codificado es: "underc0de"
y la contraseña cualquier combinación de los caracteres: "3yqa a"

Como la contraseña se codificaba como un número, resultante de la suma de números preestablecidos que codificaban los caracteres de la contraseña, la contraseña pasaba a ser un conjunto de caracteres sin importar el orden.

Utilizé este script en python para averiguar la el texto, por fuerza bruta. Se ha conseguido descifrar en 3.23 segundos.

Código: python
from time import time

TEXT_CHARACTERS = (10061, 43487, 49669, 74287, 98953, 75767, 74099, 12457, 32159, 53897, 41263, 60331, 91291, 33403, 43651, 40559, 13921, 40531, 37861, 76091, 77093, 80107, 79861, 91801, 93937, 90397)
TEXT_NUMBERS = (42683, 10037, 20101, 49121, 33151, 17029, 58013, 89867, 91199, 97259)
TEXT_SPACE = 99989

KEYS_CHARACTERS = (59077, 77447, 46061, 20897, 48673, 78571, 65963, 15161, 64399, 45497, 91129, 80429, 17377, 42013, 19183, 23099, 22699, 55457, 84871, 84659, 32569, 80777, 52289, 86111, 86291, 37781)
KEYS_NUMBERS = (39443, 89963, 85691, 79273, 49531, 30713, 63059, 59263, 70489, 26647)
KEY_SPACE = 94687

TEXTS = set(TEXT_CHARACTERS + TEXT_NUMBERS + (TEXT_SPACE,))
KEYS = KEYS_CHARACTERS + KEYS_NUMBERS + (KEY_SPACE,)

MULTIPLIER = 10**(len(str(TEXT_SPACE)))

ORD_A = ord("a")
ORD_Z = ord("z")
ORD_0 = ord("0")
ORD_9 = ord("9")

class CharacterConverter:

def __init__(self, characters, numbers, space):
if len(characters) != ORD_Z - ORD_A + 1:
raise ValueError("longitud de la tupla de caracteres errónea")

if len(numbers) != 10:
raise ValueError("Longitud de la tupla de números errónea")

self.characters = characters
self.numbers = numbers
self.space = space


def getNumber(self, character):
if character == " ":
return self.space

n = ord(character)

if n >= ORD_0 and n <= ORD_9:
return self.numbers[n - ORD_0]

elif n >= ORD_A and n <= ORD_Z:
return self.characters[n - ORD_A]

else:
raise ValueError("Caracter no válido")

def getCharacter(self, number):
if number == self.space:
return " "

elif number in self.numbers:
return chr(self.numbers.index(number) + ORD_0)

elif number in self.characters:
return chr(self.characters.index(number) + ORD_A)

else:
raise ValueError("Número no encontrado")


TEXT_CONVERTER = CharacterConverter(TEXT_CHARACTERS, TEXT_NUMBERS, TEXT_SPACE)
KEY_CONVERTER = CharacterConverter(KEYS_CHARACTERS, KEYS_NUMBERS, KEY_SPACE)

passwordToKey = lambda password: sum(map(KEY_CONVERTER.getNumber, password))

def encode(text, password):
"""Codifica el texto que se pasa como parámetro con la contraseña indicada
text: Texto a codificar
password: Contraseña para codificar"""
num = 0

for elem in text:
num = num * MULTIPLIER + TEXT_CONVERTER.getNumber(elem)

key = passwordToKey(password)
return num * key


def decode(encodedCode, password):
"""Decodifica el mensaje con la contraseña indicada y devuelve el texto original
encodedCode: Mensaje a decodificar
password: Contraseña para decodificar"""
key = passwordToKey(password)

num = encodedCode // key
return numberToText(num)


def numberToText(num):
decoded = ""

while num > 0:
decoded += TEXT_CONVERTER.getCharacter(num % MULTIPLIER)
num //= MULTIPLIER

return decoded[::-1]


def decodeGuessingPassword_passAsSet(encodedCode, maxPassSize=4):
"""Devuelve el texto correspondiente a la decodificacion del mennsaje
prueba con todas las contraseñas hasta la longitud indicada
Trata las contraseñas como un conjunto de caracteres, sin orden
encodedCode: Texto codificado
maxPassSize: Longitud máxima de la contraseña"""

notFound = True
currentKeyData = [0]
curSize = len(currentKeyData)
maxVal = len(KEYS) - 1

while len(currentKeyData) <= maxPassSize and notFound:

if checkValidDecodedMsg(encodedCode // sum((KEYS[pos] for pos in currentKeyData))):
notFound = False

else:
i = 0
while i < curSize and currentKeyData[i] == maxVal:
i += 1

if i != curSize:
currentKeyData[i] += 1
valCurentKeyData = currentKeyData[i]

for i in range(i - 1, -1, -1):
currentKeyData[i] = valCurentKeyData

else:
curSize += 1
currentKeyData = [0] * curSize

if notFound:
raise ValueError("No se ha podido decodificar")

else:
return numberToText(encodedCode // sum((KEYS[pos] for pos in currentKeyData))), getPasswordFromKeyData(currentKeyData)


def checkValidDecodedMsg(msg):
"""Comprueba que el mensaje decodificado, como múmero sea válido
msg: Mensaje a comprobar"""
while msg > 0:
if not msg % MULTIPLIER in TEXTS:
return False

msg //= MULTIPLIER

return True

#Devuelve la contrasena, pasando como parámetro un iterable con las posiciones en KEKS de los valores de la contraseña
getPasswordFromKeyData = lambda KeyData: tuple((KEY_CONVERTER.getCharacter(KEYS[pos]) for pos in KeyData))


def main():
coded = 309224446557488409754066854545005782200040975244112

t0 = time()
print("Mensaje: {}, Contraseña: {}".format(*decodeGuessingPassword_passAsSet(coded, 8))) #Aquí al leer el post undercode cambio 8 ))) (pegado) por la ubicación de las gafas de sol.
print(f"Time: {time() - t0}")


if __name__ == '__main__':
main()



Muy interesante...
Muchas gracias por la gentileza de darle seguimiento.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Abril 06, 2020, 11:39:53 AM #3 Ultima modificación: Abril 06, 2020, 11:57:48 AM por Miguel Alonso
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hola  ;)

Hoy traigo algo bastante especial, estos días he estado programando un cifrador.
Dato: Un cifrado no puede descifrase sabiendo los datos del cifrado de lo contrario es una codificación me explico:

El binario una de las codificaciones más famosas del mundo sabiendo el metodo de codificación podríamos descifrarlo. Pero con AES por ejemplo uno de los cifrados más conocidos aunque conozcamos el metodo de cifrado no podríamos descifralo por esa forma. Sabiendo esto continuemos.

He creado un cifrado, en python3 No tienes permitido ver los links. Registrarse o Entrar a mi cuenta que tiene una clave y (o al menos se intento)
no se podría descifrar sin romper la clave. Quería proponer intentar descifrar un mensaje para ver si es seguro. De esta forma la comunidad gana porque se puede jugar con el que a mi parecer es interesante y yo gano por los bugs. Win & Win.

Captura del proyecto:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


(ADVERTENCIA: Solo soporta letras minusculas y números.)
Texto cifrado: 309224446557488409754066854545005782200040975244112

Si lo conseguís ponedlo abajo en los comentarios.  :P

Saludos  :)
Antes de nada gracias axcess  :D


(El proyecto esta haciéndose por dan884075 y por mi actualmente.)

Hola después de unos días mejorando el cifrado aquí traigo una nueva versión.  :)

MEJORAS:
(Ya no tiene múltiples claves)

Estube hablando con dan884075, su algoritmo de fuerza bruta con esta versión tardaría 24 años en probar todas las combinaciones sabiendo que tenemos 37 caracteres y una password de 8 caracteres 37 elevado a 8 nos salen unas 3512479453921 de probabilidades dijo que python3 es MUY lento que pasándolo a c podría acelerarlo unas 1500 veces  :'( pero aproximadamente son 8 días. Eso esta por ver. La verdad estoy muy contento con el resultado espero que lo disfruten tanto como yo  ;)

Próximas mejoras:

-Crear una librería de python con este cifrado.

-Poder cifrar archivos.(Esto se podría hacer con un par de lineas de código actualmente el problema es que ocuparía mucho más espacio voy a ver la forma de optimizar.)

-Meter todos lo bites así con una clave de 8 caracteres sería 255 elevado a 8: 17878103347812890625 con 10 caracteres de password superariamos en probabilidades a la mismísima maquina enigma tenía 159 trillones de probabilidades esta con 10 caracteres de clave tendría un cuatrillón ciento sesenta y dos mil quinientos veintitrés trillones seiscientos setenta mil ciento noventa y un billones quinientos treinta y tres mil doscientos doce millones ochocientos noventa mil seiscientos veinticinco probabilidades. :o

Saludos.

Nueva versión No tienes permitido ver los links. Registrarse o Entrar a mi cuenta