CTF中Rsa常见攻击思路

CTF中Rsa常见攻击思路

RSA简介

基本原理

1.选择两个不同的大质数,计算出模数 N = p * q

2.计算欧拉函数 φ(N) = φ§φ(q)=(p-1) * (q-1),然后选择一个e (1<e<φ),并且e和φ互质

3.取e的模反数d,计算方法为:e * d ≡ 1 (mod φ(N)) (模反元素:如果两个正整数e和n互质,那么一定可以找到整数d,使得 e * d - 1 被n整除,或者说e * d被n除的余数是1。这时,d就叫做e的模反元素

4.公钥(N,e),利用公钥对明文m进行加密:c = pow(m, e, N),可以得到密文c。
5.私钥(N,d),利用私钥对密文c进行解密:m = pow(c, d, N),可以得到明文m。

RSA常见攻击

模数相关攻击

暴力分解N
攻击条件

在 N 的比特位数小于 512 的时候,可以采用大整数分解的方法获取 p 和 q。

可以使用factor分解N
linux下命令
factor +n

安装factordb:

pip install factordb-pycli

也可以在线网站分解N
http://factordb.com/

共模攻击
攻击条件

当两个用户使用相同的模数 N、不同的私钥时,加密同一明文消息时即存在共模攻击。

攻击原理

当两个用户公钥分别为e1和e2,且两者互质,即gcd(e1,e2)=1 ,明文为m,密文消息分别为:

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

当攻击者截获c1和c2后,利用扩展的欧几里得算法 r* e1 + s *e2 = 1 mod n算出两个整数r和s,由此可得:

(c1 ** r)(c2 ** s) ≡  (m ** re1)(m ** se2)mod n
                   ≡  (m ** re1 + se2)mod n
                   ≡   m mod n

公钥指数相关攻击

小指数e攻击
攻击条件

如果RSA系统的公钥e选取较小的值,可以使得加密和验证签名的速度有所提高,但是如果e的选取太小,就容易受到攻击。
攻击者可以通过爆破得到m

攻击原理

假设用户使用的密钥 e=3。考虑到加密关系满足:
c ≡ m ** 3 mod n

m ** 3 = c + kn
攻击者可以从小到大枚举 k,依次开三次根,直到开出整数为止。

私钥指数相关攻击

小指数d攻击/Wiener’s Attack

在d比较小时(d < 1/3 * pow(n,1/4))
可使用算法从e中快速推断出d的值。

攻击原理

基于连分数的特殊攻击类型就可以危害 RSA 的安全
工具:

https://github.com/pablocelayes/rsa-wiener-attack

题目

分解N

yafu分解固然好用,思考一下其他解题思路

如果我们将它直接取平方根,然后取整之后的值一定在两个数之间,因为它们是通过next_prime连接的,所以可以断定它们之间一定没有质数,所以我们可以再直接通过一个next_prime得到较大的那个质数p,那么另一个质数q我们也就知道了。

import gmpy2
n = 149508848441616715934297319023960757580837139746636486446093766820602595577720613880522359931376776640771560399865570788752926866918099448386204160338951577084579042581094657939545555751085950319193925075988080113525569558968885659546782419751524189916167947489803707492932640059831396220643698853028753007377
tmp=gmpy2.iroot(n,2)[0]
p=gmpy2.next_prime(tmp)
q=n//p
print("p=",p)
print("q=",q)
共模攻击

自动随机生成例题

#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
#pow(x, y[, z])
#函数是计算 x 的 y 次方,如果 z 在存在,则再对结果进行取模
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)

由题意可以判断,n1和n2相同,初步确认为共模攻击
尝试通过欧几里得算法来得到flag

WP
#coding:utf-8
import gmpy2
import libnum

n=10509135007927020910961570498020654777820601579825669027410027026173076573380693204454238919762243178647774720169342528691085983225219960236799370268896666867164869238677749575679762611540687182614629847614275763451130215062534086871119259415866636857654106010518677919485438729877453549868724935457349692430637646827845074169704597756894678350214029352130966923159025112991395150214022844221949818486992653054085916326074567355928744181958934887632087019273037034539054980148783728604561167417571308543568511557184742388987903995431328908643666134429145944816840592528868078022503367301892068877343146684216682292031
e1=2333
c1=7817747253100075445080016685151086112268236401548478039383697586624131257005712900744875480257235019856465005133060251952853265167801711501859975585492982445693865641552507292652891995513965716569403068769379922648392091598433743576490830481993190692094310002540291082497060442504191087716491306341060343322555758506922102525722142895936303098845293736052077805416603114326241892440936798612985329887620848022507113494020806335634837064221561034485913416272720657761870572787579710754920585427628542146537468299211892356070884683021760416483687996756045071803827949139730328011630778732391114457251096093112357217218
n2=10509135007927020910961570498020654777820601579825669027410027026173076573380693204454238919762243178647774720169342528691085983225219960236799370268896666867164869238677749575679762611540687182614629847614275763451130215062534086871119259415866636857654106010518677919485438729877453549868724935457349692430637646827845074169704597756894678350214029352130966923159025112991395150214022844221949818486992653054085916326074567355928744181958934887632087019273037034539054980148783728604561167417571308543568511557184742388987903995431328908643666134429145944816840592528868078022503367301892068877343146684216682292031
e2=23333
c2=4005739533838233872100900192412804692746056018222370689494999429600683965220671145551011781360384072398973847079099863801781412654844344905559510784496389730242858693821886631397324132791823439680955157172958658051082121321917953586754734740594115385719917993135141183252010390389651513644552790616554115701338569755344442572426665297172781226400939991451728779259308086811204397695171302495091439788703682660000347393283282772216143916787270940246611837483151694679246528820414931162726657909701256510917389048934521382784300651451892299324944208983841733409704979351560563883697858790944929943311340614454947233485


#共模攻击
#共模攻击函数
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)
    print("e1,e2:",e1,e2)
    print(gmpy2.gcd(e1,e2))
    s = gmpy2.gcdext(e1, e2)
    print(s)
    print(s[1])
    print(s[2])
    s1 = s[1]
    s2 = -s[2]

    if s1 < 0:
        s1 = - s1
        c1 = gmpy2.invert(c1, n)
        print(c1)
    elif s2 < 0:
        s2 = - s2
        c2 = gmpy2.invert(c2, n)
    #若s1<0,则c1^s1==(c1^-1)^(-s1),其中c1^-1为c1模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)))
print(libnum.n2s(int(m)).decode())

在这里插入图片描述

小d改版

护网杯cry1

from Crypto import *
from gmpy2 import *
from random import *
from flag import flag

m = bytes_to_long(flag)

while True:
    try:
        p = getPrime(512)
        q = next_prime(p+2**420)
        n = p*q
        phi = (p-1)*(q-1)
        d = randint(0,n**0.32)
        e = inverse(d,phi)
        c = pow(m,e,n)
        break
    except:
        continue

print("e = %d"%e)
print("n = %d"%n)
print("c = %d"%c)

'''
e = 101684733522589049376051051576215902510166244234370429058800153902445053536138419222096346715560283781778705047246555278271919928248836576236044123786248907522717751222608113597458768397652361813688176017155353220911686089871315647328303370846954697334521948003485878793121446614220897034652783771882675756065
n = 106490064297459077911162044548396107234298314288687868971249318200714506925762583340058042587392504450330878677254698499363515259785914237880057943786202091010532603853142050802310895234445611880617572636397946757345480447391544962796834842717321639098108976593541239044249391398321435940436125823407760564233
c = 92367575354201067679929326801477992215675304496512806779109227230237905402825022908214026985431756172011616861246881703226244396008088878308925377019775353026444957454196182919500667632574210469783704454438904889268692709062013797002819384105191802781841741128273810101308641357704215204494382259638905571144
'''

首先分析一下题目,p是随机生成的大素数,q与p的关系为p+2** 420 附近的一个大素数,d为0到 n** 0.32的一个随机数,e为d的模反数。
明文为flag从字节转为整型,反之最终的flag为得到的明文转化为字节。
最终问题是根据题目提供的e,n,c计算出明文

从题目可以看出来 d为0到 n** 0.32
由题目给出的条件可以得到数量级大约在10**98
由于d和e的数量级太大,因此首先考虑的是小d攻击
尝试使用rsa-wiener-attack
破解无果

尝试转换思路
题目提供了p和q的关系,不同以往的题目,p,q随机生成
我们可以尝试利用他们的关系构造函数

使用SAGE自带的函数组合,通过构造一个一元多次方程,先得到一个符合p或q与n的一个近似值,然后通过realField函数进行数值分析进一步得到我们想要的符合p、q关系的数(Sage能够完成从12维物体到计算全球变暖效应数学模型中的降雨量的任何事情。Sage包含了从线性代数、微积分,到密码学、数值计算、组合数学、群论、图论、数论等各种初高等数学的计算功能。)

WP
#sage
import gmpy2
import libnum

n = 106490064297459077911162044548396107234298314288687868971249318200714506925762583340058042587392504450330878677254698499363515259785914237880057943786202091010532603853142050802310895234445611880617572636397946757345480447391544962796834842717321639098108976593541239044249391398321435940436125823407760564233
e = 101684733522589049376051051576215902510166244234370429058800153902445053536138419222096346715560283781778705047246555278271919928248836576236044123786248907522717751222608113597458768397652361813688176017155353220911686089871315647328303370846954697334521948003485878793121446614220897034652783771882675756065
c = 92367575354201067679929326801477992215675304496512806779109227230237905402825022908214026985431756172011616861246881703226244396008088878308925377019775353026444957454196182919500667632574210469783704454438904889268692709062013797002819384105191802781841741128273810101308641357704215204494382259638905571144
RF = RealField(512) #任意精度初始化(512位精度)
x = polygen(RF)
#x = polygen((RealField(1000), 'x'))
f = x * (x + 2**420) - n
p = int(f.roots()[1][0]) #一元二次方程,取正数
#f.roots()  
print(f"p = {p}") 
while n % p != 0:
    p = p - 1

q = n//p
print(f"p = {p}") 
print(f"q = {q}")
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi) # 求大整数e模phi的逆元y
m = pow(c,d,n)  #大整数c的d次幂模n取余
flag = libnum.n2s(int(m))
print(flag)

在这里插入图片描述

参考:
https://www.freebuf.com/articles/database/290623.html
https://blog.csdn.net/luochen2436/article/details/127012150
https://blog.csdn.net/baidu_36110484/article/details/106958538
https://blog.csdn.net/fengerxi33/article/details/123007358

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值