题目如下:
from functools import reduce
from Crypto.Util.number import *
import random
from secret import flag,hint
def generate_PQ(bits):
x = getPrime(bits) >> bits//2 << bits//2#右移bit//2位后左移bit//2位
while True:
p = x + random.getrandbits(bits//2)#x是前一步生成的大素数,加上一个bit//2的随机数
if isPrime(p):#判断是否位素数
break
while True:
q = x + random.getrandbits(bits//2)
if isPrime(q):
break
return p,q
m = bytes_to_long(flag)
hint = bytes_to_long(hint)
e = 65537
p,q = generate_PQ(1024)#用generate_PQ函数生成两个大素数p,q,1024是参数
n = p*q
random.seed(seed)
x = [random.randint(1,seed) for _ in range(2)]#包含两个元素的列表,每个元素都是在指定范围内生成的伪随机整数
y = [random.randint(1,seed) for _ in range(2)]
print("c =",pow(hint,e,n))
print("n =",n)
print("c1 =",pow(reduce(lambda x, y: x * m + y, x), 17, n))#对x列表中的元素
print("c2 =",pow(reduce(lambda x, y: x * m + y, y), 17, n))#对y列表中的元素
对题目进行审计
p、q的生成逻辑如下:
def generate_PQ(bits):
x = getPrime(bits) >> bits//2 << bits//2
while True:
p = x + random.getrandbits(bits//2)
if isPrime(p):
break
while True:
q = x + random.getrandbits(bits//2)
if isPrime(q):
break
return p,q
p、q的前512位是一样的,只有后512位不同,且是 random.getrandbits()生成的。影响不大 比较接近(即认为p=q)
自己本地多试试这个生成过程之后,可以得出: p+q = 2*(gmpy2.iroot(p*q,n)[0] + 1)(gmpy2.root(q,n)用于求q的n次方根,向下取整,故+1)
因此 phi_n = n - (p+q) + 1
进而求d 正常解rsa即可(注:phi_n=(p-1)^2 , p=q)
exp如下:
from Crypto.Util.number import *
import gmpy2
c = 23001012057110779471190091625946693776382380529397302126337301229214301450335125076016991835054198112255974220434689958104931664098817350134656616154892781885504255726632558690544057380195511404078662094726952602350250840712610362029824982069179543810686494204685887486972937880502875441232004432323308734978847464589775857815430854038396134952486665687531579988133729365443247597395131516449487146786214227230853061720614077115599878358089377114269765796099004940883513036567103436154122335792598432012140232905658895014924069330265282364249236142072335363164451294973492092043110680377767954710822286121195290921259
n = 25797576442752368834409243494498462987370374608513814739930733437032797864549696772439769896270235017474841764016848627149724764584643408544417890463920153063835758878658712790547466715525246861709503145754424896044647787146006099053059124466248594151765065039034244830614724509092882854620642569723528913880146979990993657935598837645247839225413889995373643109990149255485373119338024345925311643249141660177285328457994476509430988280481564046398593906405870633323621548853838399385539924067139236445142933316057900841508972844270649504321178274091144241788883353514769368447833090379142367062327674855735832181241
c1 = 5702553209026762891130621254037294747819864952568824327221430749829654552175171307151888953348659971422228556686092434932000213695492351602755144510029319044193567051613888876933660356756790444392278614143455408803808095980542751023095024106689759843322130186219560734082292015929006937318400901378373771587448471762923415750064340829545587346927358411518874090282598069394946985795177419501659425500481799157093068337225389827654860680897913114945871197415129055139716514884716404289565297854681809258375973195355836553939670482515484347869258398517276876478311544109924573128946617113822561968330536525876279165313
c2 = 17562619948191690401152271053920025392401205523418067246455197241332062181407775133406742024747779181762812656501246379566147855594504112107873162350649668441267907193889705868572309785100582281795380779594946422800722070311908572538672508371123334385630310655242811756206073131919770939609347021343765434127086363844595938894714892990053114153402729297796655717510572619694559203260762574159375142757462082162882775921182437134358375300674547217425590072112733480640372328934982979603312597484512120618223179217692002851194538130349201457319160001114007059615596355221194709809437500052122684989302563103918409825040
e = 65537
x = gmpy2.iroot(n,2)[0]
p_and_q = x*2 + 2
phi_n = n - p_and_q + 1
d = gmpy2.invert(e,phi_n)
hint = pow(c,d,n)
print("Hint:",long_to_bytes(hint))
得到:Hint: b'Hint{Seed_is_256087_+_396445_-_538018}'
因此可以计算出 seed值为:114514
所以
-
x=[30509,13601]
-
y=[92095,27065]
可以得到:
-
c1 = (30509*m + 13601)^17 mod n
-
c2 = (92095*m + 27065)^17 mod n
明文存在线性关系类型题目,可以按rsa再次解密一下
也可以利用 ** Related Message Attack**
sagemath exp如下:
#Related Message Attack 解题脚本
# 条件:已知 e、n c1 = (a*m+b)^e mod n c2 = (c*m+d)^e mod n
# 即相同的公钥[e, n]去加密线性变换后的m
#Sage
import binascii
def attack(c1, c2, n, e):
PR.<x>=PolynomialRing(Zmod(n))
# replace a,b,c,d
g1 = (30509*x+13601)^e - c1
g2 = (92095*x+27065)^e - c2
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()
return -gcd(g1, g2)[0]
n = 25797576442752368834409243494498462987370374608513814739930733437032797864549696772439769896270235017474841764016848627149724764584643408544417890463920153063835758878658712790547466715525246861709503145754424896044647787146006099053059124466248594151765065039034244830614724509092882854620642569723528913880146979990993657935598837645247839225413889995373643109990149255485373119338024345925311643249141660177285328457994476509430988280481564046398593906405870633323621548853838399385539924067139236445142933316057900841508972844270649504321178274091144241788883353514769368447833090379142367062327674855735832181241
c1 = 5702553209026762891130621254037294747819864952568824327221430749829654552175171307151888953348659971422228556686092434932000213695492351602755144510029319044193567051613888876933660356756790444392278614143455408803808095980542751023095024106689759843322130186219560734082292015929006937318400901378373771587448471762923415750064340829545587346927358411518874090282598069394946985795177419501659425500481799157093068337225389827654860680897913114945871197415129055139716514884716404289565297854681809258375973195355836553939670482515484347869258398517276876478311544109924573128946617113822561968330536525876279165313
c2 = 17562619948191690401152271053920025392401205523418067246455197241332062181407775133406742024747779181762812656501246379566147855594504112107873162350649668441267907193889705868572309785100582281795380779594946422800722070311908572538672508371123334385630310655242811756206073131919770939609347021343765434127086363844595938894714892990053114153402729297796655717510572619694559203260762574159375142757462082162882775921182437134358375300674547217425590072112733480640372328934982979603312597484512120618223179217692002851194538130349201457319160001114007059615596355221194709809437500052122684989302563103918409825040
e = 17
m1 = attack(c1, c2, n, e)
print(binascii.unhexlify("%x" % int(m1)))
得到flag:b'HECTF{r3411y_easy_R4nd0m_And_r3l4ted_m3554ge_att4ck}'