题目:
from Crypto.Util.number import *
from gmpy2 import *
from tqdm import *
# flag = b'ZLCTF{记得那年的雨季,回忆里特安静,哭过后的决定,是否还能进行}'
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 65537
c = pow(m, e, n)
p = p >> 16 << 16
fake_q = getPrime(512)
print(f"fake_q={fake_q}")
print(f"p={p}")
print(f"c={c}")
# fake_q=11358116569351455987642061919486173193666865437811944699248803602510841188238240673421463544592812927197175120220714909131109370587605255655860930426830277
# p=7026532484145123601465506145053956952025279992931701315951466204294921224708118794315480042857064698938606552069520998232896450701843030854266779442806784
# c=2728908285295344891352459363943545549057138510514512112447843375558932936263981581886083647309884336063754417566205645582391386031156751212259327137826178953978694493195692003795584382217213399859668996090149830454888815597566731943943430435100546816100591081338169757531164543239052769807942657020328141496
解题思路:
- p>>16<<16表示在向右移动16位之后,结果再向左移动16位,在向左移动时,最低位(最右边的位)被填充为0,这意味着在上一步中移动到最高16位的那些位现在将回到它们原来的位置,而原来的最高16位(在向右移动时被丢弃的那些位)将被0填充
- 因为p丢失的高位并不多,所以我直接穷举了p的后16位数
- 这里比较坑的是这个q真的是假的
- 知道n=p后就是常规的RSA解密了
解答:
from Crypto.Util.number import *
from gmpy2 import *
c= 2728908285295344891352459363943545549057138510514512112447843375558932936263981581886083647309884336063754417566205645582391386031156751212259327137826178953978694493195692003795584382217213399859668996090149830454888815597566731943943430435100546816100591081338169757531164543239052769807942657020328141496
e= 65537
#p_low= 7026532484145123601465506145053956952025279992931701315951466204294921224708118794315480042857064698938606552069520998232896450701843030854266779442806784
#p_low_prefix= hex(p_low)
p_low_prefix= "8628f9b0ae90f7c24b2c6734c6485c8cf2b929c162525e584c87fd78afd4bcc6b4bb2fdf56b328dca56d1e8075154847f0bb86932af1c82d230aa1cf7fb3"
for i in range(256*256):
suffix = format(i, '04x') # 生成 0000 到 ffff 的所有 16 进制组合
p = int(p_low_prefix + suffix, 16)
if is_prime(p):
phi = (p - 1)
d = invert(e, phi)
m = pow(c, d, p)
if b'ZLCTF' in long_to_bytes(m):
print(long_to_bytes(m))
#ZLCTF{fl4g_is_t00_5h0rt_th4n_p}