Crypto(11)HECTF-rsarsa(明文存在线性关系)

题目如下:

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}' 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值