Bancarrota
Categoría: Crypto Dificultad: Hard
Descripción del reto
El reto entrega un output.txt con los siguientes datos públicos:
n = 88414814868035811675053476790757183219833077857790658518374191743395116845115061528008085663634920575725860680618605233668935227198665125936037136388097458649126677107202112594942802316604869417510426361858052660647273709287613460403410412181509561538712695138630895924830183589161717870494320335995725649113
e = 65537
c = 30250981509850990129207765287429103048296430271684860662908644684691614716869020256328990837924296007698218340267714279683758265003409499090708049047183680954260669691735105649990968201405808149637466756340163849831054862762698907574073537414698212342127587114243405245474354105150576516832016218254233551030
p_msb = 6384482865957816600821075381730956442412139232241618654154874067983428432778076832168977
unknown_bits = 220El enunciado indica que el sistema RSA de una entidad bancaria ha filtrado los bits más significativos de uno de los primos usados para generar la clave.
La pregunta real del reto es:
¿Se puede romper RSA si solo conocemos una parte de uno de sus factores?
La respuesta es sí, si esa parte filtrada es suficientemente grande y la parte desconocida es suficientemente pequeña como para usar un ataque de Coppersmith / small roots.
1. Análisis inicial
En un RSA estándar se publica:
ney a veces el ciphertext
c
Pero aquí aparece además:
p_msbunknown_bits
Eso ya indica que no estamos ante un RSA “normal”, sino ante un RSA con fuga parcial de clave.
Un jugador que vea esto debería pensar inmediatamente:
p_msbrepresenta la parte alta depfaltan
unknown_bitsbits por recuperarpor tanto,
ppuede modelarse como una parte conocida más una parte pequeña desconocida
La observación clave es:
donde:
p_msb << unknown_bitses la parte conocida depxes la parte desconociday
x < 2^unknown_bits
En este reto:
conocemos todos los bits altos de
pfaltan 220 bits bajos
eso hace que
xsea una raíz pequeña
Y ahí es donde entra Coppersmith.
2. Fundamento teórico
RSA usa dos primos p y q para construir:
La seguridad depende de que factorizar n sea difícil.
Pero si conocemos parcialmente uno de esos primos, podemos escribir:
donde:
aes la parte conocidaxes la parte desconocida y pequeña
En este caso:
y el primo real es:
Como p divide a n, si logramos recuperar x, recuperamos p, luego q, y RSA queda roto por completo.
El método de Coppersmith permite encontrar raíces pequeñas de polinomios módulo un entero compuesto. Aquí usamos el polinomio:
y buscamos una raíz pequeña x tal que:
con p divisor de n.
3. Idea del ataque
El atacante piensa así:
Tengo
n,e,cy una fuga parcial depConstruyo la parte conocida:
Escribo:
Como
xes pequeño, pruebo un ataque desmall_rootsRecupero
pCalculo
q = n / pRecupero
dDescifro
c
4. Solución con Sage
La forma práctica y estándar de resolver este tipo de reto en CTF es con SageMath.
Script completo
5. Explicación detallada del script
5.1 Carga de datos
Aquí se cargan los parámetros públicos del reto.
nes el módulo RSAees el exponente públicoces el ciphertextp_msbes la parte alta filtrada del primopunknown_bitsindica cuántos bits faltan
5.2 Reconstrucción parcial de p
Desplazar a la izquierda unknown_bits posiciones equivale a colocar los bits altos en su posición correcta dentro del entero.
Eso construye la parte conocida del primo:
pero aún faltan los bits bajos:
5.3 Construcción del polinomio
Esto define el polinomio:
trabajando módulo n.
La idea es que queremos encontrar un valor pequeño x tal que a + x sea realmente el factor p de n.
5.4 Búsqueda de raíz pequeña
Esta es la parte central del ataque.
Coppersmith permite encontrar raíces pequeñas de polinomios módulo un entero compuesto. Aquí le decimos a Sage:
X= tamaño máximo aproximado de la raízbeta= parámetro del algoritmo
El script prueba varias combinaciones porque en la práctica algunas instancias necesitan pequeños ajustes para converger.
5.5 Validación del candidato
Aunque small_roots devuelva algo, siempre hay que comprobar que de verdad factoriza n.
Si p divide a n, entonces hemos recuperado el primo correcto.
5.6 Recuperación de q
Una vez recuperado p, el otro factor es inmediato.
5.7 Cálculo de la clave privada
Con los factores ya obtenidos, RSA se rompe de forma estándar:
calculamos
phi(n)calculamos el inverso modular de
eobtenemos
d
5.8 Descifrado
Aplicamos la fórmula RSA de descifrado:
5.9 Conversión a texto
Esto transforma el entero descifrado en bytes y luego en texto legible.
6. Resultado
La salida del script es:
Este reto demuestra una idea muy importante en criptografía aplicada:
RSA no solo falla si alguien factoriza
npor fuerza bruta; también puede romperse si se filtra suficiente información parcial sobre uno de sus factores.
Last updated