[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次方根
由于这里我们假设z与p
和q
有关,我们可以推测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:]))
写出该脚本的思路:
- 导入必要的库:
gmpy2
sympy.crypto
- 定义RSA参数:e,d,c
- 尝试通过
e
和d
恢复模数n
:- 这部分代码试图通过暴力搜索的方式来找到
p
和q
,从而恢复模数n
。然而,这种方法在实际应用中是不可取的,因为它效率低下且不一定能成功。 - 它首先计算
e_d_1 = e * d - 1
,并假设e_d_1
可以表示为(p-1)*(q-1)*k的形式,其中k是一个介于2^15和2^16
之间的整数。 - 然后,它遍历这个范围内的所有k值,并试图找到满足条件的
p
和q
。 - 如果找到了满足条件的
p
和q
,则计算n = p * q
。
- 这部分代码试图通过暴力搜索的方式来找到
- 解密密文:使用
gmpy2.powmod(c, d, n)
函数进行模幂运算, - 将解密后的数值转换为可读的格式:
- 使用
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)
出题代码思路:
- 导入库
- 定义RSA公钥的模数
n
、两个加密指数e1
和e2
、以及两个密文c1
和c2
。 - 定义共模攻击函数
rsa_gong_N_def
:- 函数接收五个参数:
e1
、e2
、c1
、c2
和n
。 - 首先,将输入参数转换为整数类型,确保所有操作都在整数域进行。
- 使用
gmpy2.gcdext
函数计算e1
和e2
的扩展欧几里得算法结果。该函数返回一个三元组(g, x, y)
,其中g
是e1
和e2
的最大公约数(在此场景下应为1,因为e1
和e2
互质),而x
和y
是满足x*e1 + y*e2 = g
的整数。 - 从
gcdext
的结果中提取x
和y
的等价值s1
和s2
,确保它们是非负的(如果需要,通过取反和模反元素来调整)。 - 如果
s1
是负数,则取s1
的相反数,并使用gmpy2.invert
函数计算c1
在模n
下的模反元素(因为(a^-1)^-1 = a
在模运算下成立)。 - 如果
s2
是负数,则进行类似的调整,对s2
取相反数并计算c2
的模反元素。 - 使用调整后的
s1
、s2
、c1
(如果需要取模反)和c2
(如果需要取模反),以及公钥n
,计算m = (c1^s1 * c2^s2) mod n
。这是基于RSA加密的幂运算性质和扩展欧几里得算法的结果。 - 返回计算得到的明文整数
m
。
- 函数接收五个参数:
- 执行共模攻击并打印结果:调用
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的情况下,可以进行解密。