[*CTF 2022]ezRSA

这是一道经典的对于p的处理和获得部分p值的patral-p问题求解,这种求解方法对于大量类似题型有极大的借鉴意义。

from Crypto.Util.number import getStrongPrime
from gmpy import next_prime
from random import getrandbits
from flag import flag

p=getStrongPrime(1024)
q=next_prime(p^((1<<900)-1)^getrandbits(300))
n=p*q
e=65537

m=int(flag.encode('hex'),16)
assert m

首先,我们分析题目,可知p是随机的,q是基于p生成的,其中p和q的后124为bit数值相同,q后900bit与(1<<900)-1)^getrandbits(300)进行异或求得,其中,中间600bit的部分我们可以求出。

第一步:

求出前124bit

p = k1 * (2^900) + k2

q = k1 * (2^900) + (2^900 - k2) +k3

n = p*q = k1^2 * (2^1800) + 2k1k2 * (2^900) + k1 * (2^1800) + L(可忽略不计)

我们即可对n//2^1800,即只剩下k1一个未知量,即可求解。

PR. = PolynomialRing(Zmod(n))
f = int(n,16)//(2^1800) - m^2 - m
x = f.small_roots()
print(x)

top_bits = 20226195070633070235386534147535171929

 第二步

我们可知,当pq越相接近时,pq相乘的值越大。所以,我们一开始将p后900bit全部设置为1,而q全部为0,进行乘法运算与n进行大小比较,这样不断接近n值,从而求得中间的600bit数值

p = top_bits<<900 | (2**900 - 1)
q = top_bits<<900
# Start from 125th bits (1024-125)
for i in range(899, 301, -1):
	cur = 1<

 最后,就是典型的部分p泄露脚本带入即可。

PR. = PolynomialRing(Zmod(n))
f = p + x
m = f.small_roots()
print(int(p+m[0]))

sb​​​​​​​starctf2022/exp.sage at main · sixstars/starctf2022 (github.com)(标准wp可见)

你可能感兴趣的:(crypto,python,开发语言,crypto,安全)