2016 0CTF rsa
知识点:多素数,中国剩余定理,模三次剩余
题目给了一个flag.enc,还有一个public.pem
安装openssl可以读取到n和e,因为n不大,可以在yafu或者factordb.com上分解得到n = p * q * r
根据flag.enc,可以得到密文m
根据中国剩余定理,我们要求得m在p,q,r下的余数,不妨设为pmod,qmod,rmod
然后根据模三次剩余,即:proot ^ 3 ≡ pmod ( mod p),求得:proot,同理求得qroot,rroot
利用网页工具可以直接计算得到:
题解在这儿:
https://github.com/sonickun/ctf-crypto-writeups/tree/master/2016/0ctf/rsa
代码来自题解链接:
# -*- coding:utf-8 -*-
# 0CTF 2016: RSA? (Crypto 2pt)
'''
# openssl rsa -in public.pem -pubin -text -modulus
Public-Key: (314 bit)
Modulus:
02:ca:a9:c0:9d:c1:06:1e:50:7e:5b:7f:39:dd:e3:
45:5f:cf:e1:27:a2:c6:9b:62:1c:83:fd:9d:3d:3e:
aa:3a:ac:42:14:7c:d7:18:8c:53
Exponent: 3 (0x3)
Modulus=2CAA9C09DC1061E507E5B7F39DDE3455FCFE127A2C69B621C83FD9D3D3EAA3AAC42147CD7188C53
writing RSA key
-----BEGIN PUBLIC KEY-----
MEEwDQYJKoZIhvcNAQEBBQADMAAwLQIoAsqpwJ3BBh5Qflt/Od3jRV/P4Seixpti
HIP9nT0+qjqsQhR81xiMUwIBAw==
-----END PUBLIC KEY-----
'''
# Chinese Remainder Theorem
def chinese_remainder(n, a):
sum = 0
prod = reduce(lambda a, b: a*b, n)
for n_i, a_i in zip(n, a):
p = prod / n_i
sum += a_i * mul_inv(p, n_i) * p
return sum % prod
def mul_inv(a, b):
b0 = b
x0, x1 = 0, 1
if b == 1: return 1
while a > 1:
q = a / b
a, b = b, a%b
x0, x1 = x1 - q * x0, x0
if x1 < 0: x1 += b0
return x1
e = 3
n = 0x2CAA9C09DC1061E507E5B7F39DDE3455FCFE127A2C69B621C83FD9D3D3EAA3AAC42147CD7188C53
# Factorize n using factordb.com
p = 26440615366395242196516853423447
q = 27038194053540661979045656526063
r = 32581479300404876772405716877547
assert p * q * r == n
ct = int(open("flag.enc", "rb").read().encode("hex"), 16)
# ct = 2485360255306619684345131431867350432205477625621366642887752720125176463993839766742234027524
# pt^3 mod p = ct mod p = 20827907988103030784078915883129
# pt^3 mod q = ct mod q = 19342563376936634263836075415482
# pt^3 mod r = ct mod r = 10525283947807760227880406671000
# Calculate possible cube-root
# using wolflam alpha (or using modified Tonelli-Shanks algorithm)
# like this: "x^3 = 20827907988103030784078915883129 (mod 26440615366395242196516853423447)"
p_root = [5686385026105901867473638678946, 7379361747422713811654086477766, 13374868592866626517389128266735]
q_root = [19616973567618515464515107624812]
r_root = [6149264605288583791069539134541, 13028011585706956936052628027629, 13404203109409336045283549715377]
# For every compination of roots, mix them using Chinese Remainder Theorem
for x in p_root:
for y in q_root:
for z in r_root:
m = chinese_remainder([p, q, r], [x, y, z])
pt = hex(m)[2:-1]
if len(pt) % 2 != 0:
pt = "0"+pt
pt = pt.decode("hex")
if pt.find("0ctf{") >= 0:
# Get the flag
print pt.strip()
break
# Result
# > python solver.py
# �^˄�RC�J0ctf{HahA!Thi5_1s_n0T_rSa~}