RSA专题+buuctf RSA专项练习

类型一 已知dp,dq,p,q,c求解明文

推导过程

欧拉定理,模反元素

        欧拉定理 也就是一个数n如果能够被分解成为两个数p和q 那么       \phi (n)=(p-1)(q-1)

        模反元素 建立在欧拉定理的基础之上 如果两个数a和n互素 则存在  a^{\phi (n)}\equiv 1(mod n)

        由此可以得出私钥的求解公式

结论

        

        得到上述结论后 做题的步骤就可以简化为以下几步了

  1. 求解逆元
  2. 带求解m1,m2(只是把证明过程中m1,m2中c的指数变成dp和dq)
  3. 带入公式求解明文m

练习 buuctf RSA1

        题目信息

        题中只给出了dp,dq,p,q,c的值 我们直接用上面的步骤结合脚本解题就行

        脚本

        注意:解出来的是十进制的大数 需要将其转换成16进制 再转换成字符 就能得到flag 但是提交的时候需要将其包壳换成flag{}的格式 不然提交一直不会通过

# 步骤:1.求解逆元
# 2.求解m1,m2
# 3.求解m
import gmpy2
p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852
n = p*q
#求解逆元I
I = gmpy2.invert(p,q)
#求解m1,m2
m1 = pow(c,dp,p)
m2 = pow(c,dq,q)
#求解明文
m = ((((m2-m1)*I)%q)*p+m1)%n
print("求解出的明文是:")
print(m)

类型二 已知公钥public key 密文c 求解明文m

练习

题目信息

这个公钥我最开始以为是base64加密的 但是去尝试后发现不能解密 其实这是公钥解析 能够通过该信息解析出模数n和指数e

使用解密工具:http://www.hiencode.com/pub_asys.html
公钥解密工具(主要是针对RSA的公钥,私钥对的加密解密):RSA公私钥分解 Exponent、Modulus,Rsa公私钥指数、系数(模数)分解--查错网

 解密后得到n为65537 n为86934482296048119190666062003494800588905656017203025617216654058378322103517

 使用在线工具进行大数分解:factordb.com

分解后得到p和q 就可以使用rsa库中的PrivateKey函数得到私钥key(n,d)对密文flag.enc进行解密 脚本如下

#脚本

# 步骤:1.求解d
# 2.使用rsa库中的privatekey函数求解私钥
# 3.利用私钥对flag.enc进行解密
import rsa
import gmpy2


e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463

phin = (p - 1) * (q - 1)
d = gmpy2.invert(e, phin)

key = rsa.PrivateKey(n, e, int(d), p, q)

with open("D:/desktop/ctf题目/flag.enc", "rb") as f:
    f = f.read()
    print(rsa.decrypt(f, key))

类型三 已知n,dp,c,e,求解明文m

推导过程

由上变换,再结合dp<p-1

为什么dp会比p-1更小呢?

在RSA加密过程中,因为由上图的加密原理可知,e与n的欧拉函数天生是互素的,且e比n的欧拉函数更小,要选择一个数与e相乘后是欧拉函数的倍数,那这个数只能在1到n的欧拉函数之间,而且d应该越小越有利于加密。所以在p极大的情况下d*p<p-1是成立的

那么dpe<(p-1)*e,也就是(k2*(q-1)+k1)<e

好了,求出这个表达式的值有什么用呢?

因为dp和e的值我们都知道,所以dp与e的乘积我们也知道,而且在等号右边中我们知道(k2*(q-1)+k1)的范围,那么我们只需要设置循环(1到e之间),只要满足(dpe-1)能整除循环数,那么就说明我们找到了(p-1)的值,求出p的值后,如果n能整除p的话那么就说明我们寻找到的p值是正确的


dp<p-1(当p较大时)最好当成结论记住

练习 buuctf RSA2

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751

脚本

# 步骤:1.寻找i i满足dpe-1整除i
# 2.由i计算得到可能的p值
# 3.判断n是否能够整除得到的可能的p值 如果可以 就找到了p值
# 4.根据p dp 可以得到d 直接解密即可

import gmpy2

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
for i in range(1,e):
    if (dp*e-1)%i==0:
        #代表此时的i可能是(p-1)的值
        x = (dp*e-1)//i+1
        if n%x==0:
            p=x
            q = n//p
            break
print("找的的p值是:",end='')
print(p)
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print("找到的明文是:",end='')
print(hex(m))

         得到十六进制的数据后 找个在线网站转换成字符串即可。这里要注意的是 并不能直接用dp除以p 因为数过于大 最终结果是0 只能从定义出发得到d

类型四 共模攻击

关于共模攻击

什么是共模攻击

1.攻击者选取使用相同n值的两个用户A和B。A的加密指数是e1,B的加密指数是e2。 

2. 攻击者选择明文m,并使用A和B的加密公钥分别加密得到密文c1和c2。

3. 因为使用相同n值,c1的解是m的e1次方模n,c2的解是m的e2次方模n。

4. 根据上两条等式可以解出m的值,得到明文,达到破解RSA算法的目的。所以,共模攻击的要点是利用多个用户使用相同模数n的漏洞。它比公模攻击严重得多,应该在RSA应用中避免使用相同的n值来防范这种攻击

推理过程

 脚本


# 步骤:1.先寻找s1,s2
# 2.套公式求明文
import gmpy2
c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
e1=11187289
c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2=9647291

r,s1,s2 = gmpy2.gcdext(e1,e2)#这里使用的是扩展欧几里得,r是s1和s2的最大公因子,s1和s2是我们要求的数
m = (pow(c1,s1,n)*pow(c2,s2,n))%n
print("找到的明文是:")
print(hex(m))

        得到十六进制的flag后 找个在线网站直接转就行了 共模攻击直接套公式做就行了 没有难度

类型五 低指数攻击

练习

当模数n非常大,但指数e却非常小的情况。可以看做

如果m^e<n,即c=m^e,直接对c开e次方就可以

如果m^e>n,即m^e=kn+c,此时可以对k进行爆破,找到满足条件的k,然后对kn+c开e次方即可得到明文m

 脚本

from gmpy2 import iroot

n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
e = 0x3

k = 0
while 1:
    res = iroot(k*n+c,e)#对kn+c进行开方
    if res[1]==True:#说明此时开方正确 找到了对应的k的值
        print(hex(res[0]))
        break
    k+=1

        同样获得十六进制的结果后 找一个在线网站转一下字符串就可以了(我不会用python的函数 所以一直用的是在线转的网站)

今日总结:今天主要是复习了关于rsa的相关题型 复习了几种比较大的 比较复杂的类型 还有一些题型没有弄到博客上面是因为不是特别具有代表性 明天的任务就是继续刷刷题 看啊看rsa的其他的题型 然后今天收尾的话就去把上学期的操作系统的笔记整理出来吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值