202507_QQ_RSA_jiami
Tags:RSA
,素数复用
0x00. 题目
附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件
附件名称:20250727_QQ_jiami.zip
jiami.py
#! /usr/bin/python2.7
from Crypto.Util.number import size,bytes_to_long,getStrongPrime
from itertools import combinations
msg = bytes_to_long("Your secret flag is : flag{**************************}")
e = 65537
pri = []
f = open('cipherx.txt', 'w')
for i in range(5):
pri.append(getStrongPrime(1024,65537))
for k in combinations(pri, 2):
n = k[0] * k[1]
print k[0],k[1]
f.write(str(pow(msg, e, n)) + '\n')
0x01. WP
1. 解题思路
从加密代码jiami.py
来看,脚本生成了5个随机素数,并两两组合生成n,并对同一明文进行加密,所以必然存在不同n
之间存在共有的质因数,尝试对不同的c
求GCD
来得到可能出现的质因数,然后再遍历尝试解密。
2. exp.py
#!/usr/bin/python3
from Crypto.Util.number import *
from itertools import combinations
with open('miwen.txt', 'r') as f:
ciphers = [int(line.strip()) for line in f]
lstP=[]
# 从十个密文中,选择任意四个密文,计算它们之间的差值的GCD。
# 例如,假设选择密文c1, c2, c3, c4,计算:gcd(c1 - c2, c1 - c3)
# 假设得到g。如果g是一个1024位的素数,那么可能就是某个pri素数
# 通过循环遍历得到素数列表
for i in range(len(ciphers)):
for j in range(len(ciphers)):
for k in range(len(ciphers)):
if i==j:
continue
if j==k:
continue
if i==k:
continue
intTmp1 = ciphers[i]-ciphers[j]
intTmp2 = ciphers[i]-ciphers[k]
intGCD = GCD(intTmp1,intTmp2)
if isPrime(intGCD) and intGCD>1000:
if intGCD not in lstP:
lstP.append(intGCD)
print(intGCD)
'''
135975571838217118121668296935482603457076253375421353854735787837073258790233032899493205575381427464178992119737018022930393552612843525772903632327748741571081465850899045988823008547746714750863330999452022623942864133711974303817878911855669148062382727427422072684496618645865293994815975254773732292393
133035614088769590606957546090196172114084762957499619905302260213998020444446444665468835115488476270170300731796829963449195560082765360948210075220012676881738744799819394088472725659532796187349901423690920635172269978486264863267376443577335538584515967206613161811408626759353749343327165983004452661929
172480202414215578357080102524744552738454937035507415909463408965422501821985989182667677879734648421015948893433888756739081134198882605373971863953416849416808239334696379869957285211519722926699565239595195651637544739264391941597990168235725742474351753546356323755685872604835207926332453003853682781209
176266887485283989652569355958279630900249945507503054819740567821285741642140751914551729594212091613098842488673475409238354821502528636715236158938107970855395964548570473952040525655999234705653789893165018080131171323604214214043030166589010431936586129417777255968028558325911128027492229157991211695501
'''
e=65537
# 循环从素数列表中取2个进行RSA解密
for p in combinations(lstP, 2):
n=p[0]*p[1]
phi_n = (p[0]-1) * (p[1] - 1)
d = inverse(e, phi_n)
m = pow(ciphers[0],d, n)
mi = long_to_bytes(m)
print('p=',p[0])
print('q=',p[1])
print('m=',m)
print("STRIING:",mi)
print("="*32)
'''
p= 135975571838217118121668296935482603457076253375421353854735787837073258790233032899493205575381427464178992119737018022930393552612843525772903632327748741571081465850899045988823008547746714750863330999452022623942864133711974303817878911855669148062382727427422072684496618645865293994815975254773732292393
q= 133035614088769590606957546090196172114084762957499619905302260213998020444446444665468835115488476270170300731796829963449195560082765360948210075220012676881738744799819394088472725659532796187349901423690920635172269978486264863267376443577335538584515967206613161811408626759353749343327165983004452661929
m= 1090604633063547002095935464356536524760380220435610881323923236004985586808612692413698710797570336522084249769885069269566294694496507287188605
STRIING: b'Your secret flag is : flag{de8542f2b640980fbfc1ebef8e597624}'
'''
最终flag
为flag{de8542f2b640980fbfc1ebef8e597624}