Buuctf的RSA(四)

[BJDCTF2020]easyrsa

题目:

简单分析一下,有个特殊的

z=Fraction(1,Derivative(arctan(p),p))-Fraction(1,Derivative(arth(q),q))

经查询,

​​​​​​Derivative(f(x),x)   :用来求倒数

Fraction(a,b)   = a/b

arctan,arth的导函数分别为(1/1+x^2),(1/1-x^2)

最终,z=p^2+q^2

接下来的话,一开始题目下面的一大串数分别为c,z,n

from Crypto.Util.number import *
from gmpy2 import *

c = 7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035
z = 32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482
n = 15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441

paddq, mod = iroot(z + 2 * n, 2)
pmulq, mod = iroot(z - 2 * n, 2)
p = (paddq + pmulq) // 2
q = paddq - p
e = 65537
phi = (q - 1) * (p - 1)
d = invert(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)

代码中的,

iroot方法被用来寻找整数的平方根,具体来说就是,iroot(a,b)会返回 (x,exact),其中x是a的b次方根,exact是一个布尔值,表示x是否是a的精确b次方根

由于这里我们假设zpq有关,我们可以推测z可能是(p+q)的平方的一半减一(即((p+q)/2)^2 - 1)。这样,通过添加或减去2n(即2pq),我们可以使表达式更接近一个完全平方数,从而更容易找到其平方根。

然后,我们可以假设paddq(p+q)/2,而pmulq(p-q)/2(或者它们的相反数,取决于z的确切定义和iroot的返回值)。

[NCTF2019]babyRSA

题目:

遇到了  nextPrime(n)函数

      这个函数用于找到一个大于给定数字N的最小素数。如果n是偶数,则将其增加2(因为除了2以外的偶数都不是素数)。使用while循环和isPrime函数(来自Crypto.Util.number)来检查n是否为素数,如果不是,则继续增加2。

   p = getPrime(1024): 使用getPrime函数生成一个1024位的随机素数。

   q = nextPrime(p): 使用之前定义的nextPrime函数生成一个大于P的最小素数。

现在是知道了d和e,c

RSA加密原理:ed=1%(p-1)(q-1),ed-1=k*(p-1)(q-1)

e=0x10001
d = 19275778946037899718035455438175509175723911466127462154506916564101519923603308900331427601983476886255849200332374081996442976307058597390881168155862238533018621944733299208108185814179466844504468163200369996564265921022888670062554504758512453217434777820468049494313818291727050400752551716550403647148197148884408264686846693842118387217753516963449753809860354047619256787869400297858568139700396567519469825398575103885487624463424429913017729585620877168171603444111464692841379661112075123399343270610272287865200880398193573260848268633461983435015031227070217852728240847398084414687146397303110709214913
c = 5382723168073828110696168558294206681757991149022777821127563301413483223874527233300721180839298617076705685041174247415826157096583055069337393987892262764211225227035880754417457056723909135525244957935906902665679777101130111392780237502928656225705262431431953003520093932924375902111280077255205118217436744112064069429678632923259898627997145803892753989255615273140300021040654505901442787810653626524305706316663169341797205752938755590056568986738227803487467274114398257187962140796551136220532809687606867385639367743705527511680719955380746377631156468689844150878381460560990755652899449340045313521804
import sympy.crypto
import gmpy2
e_d_1=e*d-1
p=0
q=0
for k in range(pow(2,15),pow(2,16)):
    if e_d_1%k==0:
        p=sympy.prevprime(gmpy2.iroot(e_d_1//k,2)[0])
        q=sympy.nextprime(p)
        if (p-1)*(q-1)*k==e_d_1:
            break
n=p*q
print(n)
m=gmpy2.powmod(c,d,n)
print(m)
import binascii
print(binascii.unhexlify(hex(m)[2:]))

写出该脚本的思路:

  1. 导入必要的库gmpy2  sympy.crypto
  2. 定义RSA参数:e,d,c
  3. 尝试通过ed恢复模数n
    • 这部分代码试图通过暴力搜索的方式来找到pq,从而恢复模数n。然而,这种方法在实际应用中是不可取的,因为它效率低下且不一定能成功。
    • 它首先计算e_d_1 = e * d - 1,并假设e_d_1可以表示为(p-1)*(q-1)*k的形式,其中k是一个介于2^152^16之间的整数。
    • 然后,它遍历这个范围内的所有k值,并试图找到满足条件的pq
    • 如果找到了满足条件的pq,则计算n = p * q
  4. 解密密文:使用gmpy2.powmod(c, d, n)函数进行模幂运算,
  5. 将解密后的数值转换为可读的格式
    • 使用hex(m)[2:]m转换为十六进制字符串(去掉开头的'0x')。
    • 使用binascii.unhexlify将十六进制字符串转换回字节串。

总结:共模攻击

       自己写个题来让你理解:

#coding:utf-8
import libnum
import gmpy2
#生成素数
p=libnum.generate_prime(1024)
q=libnum.generate_prime(1024)
e1=2333
e2=23333

#共模攻击
m="flag{6ed4c74e022cb18c8039e96de93aa9ce}"
m=libnum.s2n(m)
n=p*q
c1=pow(m,e1,n)
c2=pow(m,e2,n)
print("n1=",n)
print("e1=",e1)
print("c1=",c1)
print("n2=",n)
print("e2=",e2)
print("c2=",c2)

出题代码思路:

  1. 导入库       
  2. 定义RSA公钥的模数n、两个加密指数e1e2、以及两个密文c1c2
  3. 定义共模攻击函数rsa_gong_N_def
    • 函数接收五个参数:e1e2c1c2n
    • 首先,将输入参数转换为整数类型,确保所有操作都在整数域进行。
    • 使用gmpy2.gcdext函数计算e1e2的扩展欧几里得算法结果。该函数返回一个三元组(g, x, y),其中ge1e2的最大公约数(在此场景下应为1,因为e1e2互质),而xy是满足x*e1 + y*e2 = g的整数。
    • gcdext的结果中提取xy的等价值s1s2,确保它们是非负的(如果需要,通过取反和模反元素来调整)。
    • 如果s1是负数,则取s1的相反数,并使用gmpy2.invert函数计算c1在模n下的模反元素(因为(a^-1)^-1 = a在模运算下成立)。
    • 如果s2是负数,则进行类似的调整,对s2取相反数并计算c2的模反元素。
    • 使用调整后的s1s2c1(如果需要取模反)和c2(如果需要取模反),以及公钥n,计算m = (c1^s1 * c2^s2) mod n。这是基于RSA加密的幂运算性质和扩展欧几里得算法的结果。
    • 返回计算得到的明文整数m
  4. 执行共模攻击并打印结果:调用rsa_gong_N_def函数,打印出明文整数m。使用libnum.n2s数将明文整数m转换为字符串,并打印出来。

随机生成了p,q

解题:

#coding:utf-8
import gmpy2
import libnum

n= 25333966058003377512707481338795714713737652659944601834182685873529702913988641983855700459996104700470621411559153944988952210084014634675583566338568882440708528997808798650962116756969822211586531522430245040013570571043385238601846104615050089457836721437790715225367971106085839523500735480715155424498941150468093083816830215632716244390679417218873179734276657411907216486790815037105108306055794473002315541787461904728375164737225486501009857299717749346279371251245318729951905832578739696926931502225899707226264570557623527701806829827566904224572897378639191756878049342203546309520458672464170859577433
e1= 2333
c1= 11355981897781478907853356911752561659125575027336719997290835661089901154031171698660586203170528368228850895159361637188990782030255983633790580700032092629587631108597144196551438410868034739981960656110887650747325311613900008001234835897835613759692146419080113176963747835592656185435741504176116672174539018089139547795447109458469225330809064539216773123671814859510069089532677704482026169178543062578686794346026774853085101278125763460212801929360456888869350105294595904940799522522144740464043605342348269086324747729288399275079874271519208155039364092577755518532799345651172433227745483422620900776136
e2= 23333
c2= 1326499538902841116411674554069945581390130048432351353260154261863309471312810811160302458644816390944833633923435634961251092531893503039914793217247984595331920909367627316087404934402312358642315675486438968585084964845763881078835787872160374025547400141298650794551970291119975344578667689961134814676553190178139842507675899262024572370313939107080072875068218336255452161407859907308656094331557912187788276334833723893856310434523337557011032081467262457427167978528280339494077785813461280853735266463152709443731638714219391773144349752633555310299318290576258086971373777118482642702020599928071855133041

#共模攻击
#共模攻击函数
def rsa_gong_N_def(e1,e2,c1,c2,n):
    e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)
    s = gmpy2.gcdext(e1, e2)
    s1 = s[1]
    s2 = s[2]
    if s1 < 0:
        s1 = - s1
        c1 = gmpy2.invert(c1, n)
    elif s2 < 0:
        s2 = - s2
        c2 = gmpy2.invert(c2, n)
    m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
    return int(m)
m = rsa_gong_N_def(e1,e2,c1,c2,n)
print(m)
print(libnum.n2s(int(m)))

得到了

根据出题过程可以得到了,

先要判断e1和e2是否互质

两个及以上的公钥(n,e)来加密同一条信息m

c1 = pow(m, e1, n)
c2 = pow(m, e2, n)

e1,e2互质,则有

gcd(e1,e2)=1
根据扩展欧几里德算法 对于不完全为 0 的整数 a,b,gcd(a,b)表示 a,b 的最大公约数。那么一定存在整数 x,y 使得 gcd(a,b)=ax+by

e1*s1+e2*s2 = 1 

而且在同一m,同一n,不同e,进行加密。在不需要知道d的情况下,可以进行解密。

  • 30
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值