RSA攻击:模数分解

2023-10-04 20:42
文章标签 攻击 rsa 分解 模数

本文主要是介绍RSA攻击:模数分解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、模数分解总览

        1.1直接分解法

        1.2费马分解与Pollard_rho分解

        1.3公约数分解

        1.4其他模数分解

二、实战特训

        2.1[黑盾杯 2020]Factor

       2.2[GWCTF 2019]babyRSA

      2.3[LitCTF 2023]yafu (中级)

        2.4[RoarCTF 2019]RSA

      2.5[CISCN 2022 西南]rsa

三、总结


一、模数分解总览

        1.1直接分解法

           在RSA的通信流程中,对外保密的是私钥,但是究其本质对外隐藏的是大素数P,Q。而正是大数分解难题的原因,使得即使暴露N,即PQ之积的值暴露,破解难度也依旧很大。所以,我们只需要掌握缺失的信息P,Q即可完成解密

          但是如果N值取的很小,我们通常可以进行暴力分解,从而获取P,Q。顺带一提,在工业中我们认为2048bit以上的N是安全的。但是,在CTF竞赛中,我们几乎不会遇到2048bit以上的素数分解。所以,这里我们可以放心使用。稍后,笔者会给处自己对与N很小的理解。

          使用条件:在阅读部分书籍的密码学(crypto)部分的解析,以及一些题目经验,大部分适合直接数模分解的N一般小于512bit。该使用条件,是笔者的拙见,欢迎大家在评论区讨论。

        1.2费马分解与Pollard_rho分解

          在1.1中我们提及了,如果N值很小,那么我们可以直接分解。但是如果N值大,我们将寸步难行。可是,这种难度在于直接分解,而不是利用部分数学技巧与原理。

          例如在费马分解中,当P,Q两个值过于接近,也就是P-Q的值很小。此时,我们就可以令A = (P + Q) / 2, B = (P - Q) / 2 则 N = A^2 - B^2。其中,在具体算法实现的过程中,因为P - Q很小,所以我们可以枚举爆破。而且根据 N = PQ,且N值一般已知,就有 A^2 = B^2 + N。

          而在Pollard_rho分解中,则恰恰相反。该分解说明当P,Q相差过大时,可以被暴力分解。从费马分解的角度说,如果P - Q过大,那么P + Q就会过小。因此可以枚举P + Q暴力破解。然而该分解方式有一定的数学原理(本菜狗没学原理,赶比赛就停在应用层面先)。

          Pollard算法的原理大体是通过某一种方式获取得到A,B值。计算p = gcd(a - b, n),直到p不为1,或者a,b出现循环。返回一个“因子”p。接着,我们可以递归的计算Pollard(p)与Pollard(n/p),值得一提得是我们p == n时,返回的就是n是一个质数退出。一般我们认为B = A^2 + 1。

          这个方法很美好,但是显示很骨感。这种分解方式建立于我们知道P - Q的状态。然而,现实和比赛中,P、Q都是被隐藏的,所以我们很难判断是否可以使用这种方式破解。SO!我们只能抱着尝试的方法使用该方法

        1.3公约数分解

          公约数分解一般是建立在多组信息(密文)在加密过程中,采取了相同的大素数P。因此,我们可以通过gcd来获取一个因此P,进而得知另外一个因子。

          使用条件:出现多组密文。

        1.4其他模数分解

          一般这种分解方式也是最难的,因为会考察选手的数学能力。也就是题目会给出一些额外的数学表达式,选手根据表达式合理爆破。或者我们可以使用factordb.com进行分解。但是当数字过大时,网站会显示补全,hhh。

          使用条件:当上述方式失效,或者题目给出额外的数学式子

二、实战特训

        2.1[黑盾杯 2020]Factor

          点击这里,跳转至题目

          在本道题中,我们获取得到了一下信息,如图所示。

          这道题有许多的尝试方法,如下:

          1.因为n比较小,可以直接分解n

          2. 因为e比较小以及给出了其他的数学关系,我们可以使用小加密明文爆破+数学关系判断。

          相对来讲,分解n更为简单。所以,我们优先尝试。注意:密码学更多的是尝试,而不是一眼定方法。使用yafu工具,我们获取一下因子。

          因此,我们可以编写一下代码段。

from Crypto.Util.number import *
import sympy
import primefac
from libnum import n2s
import gmpy2
import wienerAttackn = 3454083680130687060405946528826790951695785465926614724373
e = 3
c = 1347530713288996422676156069761604101177635382955634367208
# gcd(m, n) = 1p = 17100682436035561357
q = 17172929050033177661
r = 11761833764528579549phi = (q - 1) * (r - 1) * (p - 1)
d = primefac.modinv(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

           但是,我们在运行时,发现代码报错。别急不是因为你错了,可能是因为出现了“假素数”,即(某一大素数 - 1) 是 e 的倍数。因此经过排查,发现(p - 1) % e == 0。因此剔除p。修改代码得到。

from Crypto.Util.number import *
import sympy
import primefac
from libnum import n2s
import gmpy2
import wienerAttackn = 3454083680130687060405946528826790951695785465926614724373
e = 3
c = 1347530713288996422676156069761604101177635382955634367208
# gcd(m, n) = 1p = 17100682436035561357
q = 17172929050033177661
r = 11761833764528579549phi = (q - 1) * (r - 1)
d = primefac.modinv(e, phi)
m = pow(c, d, q * r)
print(long_to_bytes(m))

          最后获取旗帜FLAG{3_RSA}。

       2.2[GWCTF 2019]babyRSA

          点击这里,跳转至题目

          根据题目附件,我们可以获取得到以下信息(未全部显示)。

          以及以下数学式:c1 = F1 + F2, c2 = F1^3 + F2^3。以及p < q。

          在这里我们获取到的信息是n值大概在2048bit。而且给出其他表达式,所以我们尝试其他数模分解法。

          首先,我们明确思路。我们需要获取c1, c2来计算得到F1、F2。然后,将F1、F2转职为字符串即可。而获取c1、c2我们需要获取p,q。所以,现在最大的难题在于p,q。在这里说明两种方式。

          方法1:关注到p,q是相邻的两个素数,如果你知道素数分布规律,即他们之间相差lnx。所以我们可以判断出 q - p 大约在1000。所以我们可以使用费马分解

          使用yafu分解得到以下结果。

         方法2(推荐掌握): 根据p < q的关系,我们可以判断出 n > p^2,所以sqrt(n) > p。所以,我们可以猜想 nextprime(sqrt(n)) == nextprime(p) == q。证明如下:

          n = n'^2 = pq = (n''^2 - d^2) ==> n'' = (p + q) / 2 > n' > p,也就是说 n' - p < q - p.建议画一个数轴理解。

import gmpy2
import sympyN=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163n = gmpy2.iroot(N, 2)[0]
q = sympy.nextprime(n)
p = n // q

          运行结果如下:其中1038 == q - p --> 验证素数分布,方法1

 

          两个方法没有优劣之分,知识方法二更贴合题意。方法一更快,但是需要我们判断p,q对应的数字。所以,按需对应选择。

          接下来获取c1,c2就简单了。

imoprt primefacphi = (p-1)*(q-1)
d = primefac.modinv(e, phi)c1 = powmod(m1, d, N)
c2 = powmod(m2, d, N)

        接下来获取F1,F2。构造二次方程x^2 - (F1 + F2)x + F1F2 = 0。使用c1,c2表示就为x^2 - c1x + (c1^2 - c2/c1)/3 = 0

A = gmpy2.mpz(1)
B = gmpy2.mpz(-c1)
C = gmpy2.mpz((c1*c1 - c2//c1)//3)
delta = gmpy2.mpz(gmpy2.iroot(B*B - 4*A*C,2)[0])
F1 = (-B - delta) // 2
F2 = (-B + delta) // 2flag1 = long_to_bytes(F1)
flag2 = long_to_bytes(F2)
print(flag1 + flag2, flag2 + flag1)

          得到旗帜FLAG{f709e0e2cfe7e530ca8972959a1033b2}

          当然你也可以使用sympy.solve来获取根。

      2.3[LitCTF 2023]yafu (中级)

        点击这里,跳转至题目

        这道题比较简单,题目就提示了使用yafu。一共会获取15个因子,这道题额外考察了欧拉函数的性质问题。解决代码如下。

p1=2151018733
p2=2201440207
p3=2315495107
p4=2585574697
p5=2719600579
p6=2758708999
p7=2767137487
p8=2906576131
p9=2923522073
p10=3354884521
p11=3355651511
p12=3989697563
p13=4021078331
p14=4044505687
p15=4171911923phi = (p1 - 1) * (p2 - 1) * (p3 - 1) * (p4 - 1) * (p5 - 1) * (p6 - 1) * (p7 - 1) * (p8 - 1) * (p9 - 1) * (p10 - 1) * (p11 - 1) * (p12 - 1) * (p13 - 1) * (p14 - 1) * (p15 - 1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

        2.4[RoarCTF 2019]RSA

          点击这里,跳转至题目

         我们可以获取信息如下。

          在这里,我们知道P、Q可能相差过大,同时我们也获取了额外信息。所以我们可以尝试使用Pollard和其他数模分解法。

          尝试Pollard,发现预估等待时间 >= 1h。果断停止尝试。

          开始尝试其他数模分解。关注到有2019次方,所以枚举x,y的范围不会特别大,我们可以接受。

A =  2683349182678714524247469512793476009861014781004924905484127480308161377768192868061561886577048646432382128960881487463427414176114486885830693959404989743229103516924432512724195654425703453612710310587164417035878308390676612592848750287387318129424195208623440294647817367740878211949147526287091298307480502897462279102572556822231669438279317474828479089719046386411971105448723910594710418093977044179949800373224354729179833393219827789389078869290217569511230868967647963089430594258815146362187250855166897553056073744582946148472068334167445499314471518357535261186318756327890016183228412253724for x in range(1, 1000):for y in range(1, 1000):D = x % yif (D != 0) :f=(((y%x)**5)%D)**2019+y**316+(y+1)//xif (f == A) :print(x, y)break

        获得x = 2, y = 83

        然后我们关注到以下两个表达式:

          因此n = p * q > x*y*z^2, 也就是 n / x / y > z^2,那我们可以像2.2那样,获取q

n =  117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127x = 2
y = 83n1 = n // 166 #可以存放
q = sympy.nextprime(gmpy2.iroot(n1, 2)[0])
p = n // q
assert isPrime(q) and isPrime(p)print("OK") #确认步骤2正确
print(p, q)

        获得p,q后,我们就可以开始正是解码

c =  41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128e = 0x10001 # e = 65537
phi = (p - 1) * (q - 1)
d = primefac.modinv(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

          获取旗帜FLAG{wm-l1l1ll1l1l1l111ll}

      2.5[CISCN 2022 西南]rsa

          点击这里,跳转至题目

          题目附件内容如下:

from Crypto.Util.number import *
import gmpy2flag = b'XXXXXXXX'
p1 = getPrime(700)
r1 = getPrime(700)
for i in range(10):q1 = 5*p1+i
n = p1*q1*r1
p3 = pow(p1,3,n)
q3 = pow(q1,3,n)print(p3)
print(q3)
'''
p3 = 29914513810588158800677413177910972738704129106546850855032986405861482276089830788972187432277517348644647399654780884571794069905291936470934226328931651386658328163535027343107140438177837479649822914209171476632450951930287641742344330471734177295804718555774395704231261550376220154493373703096062950390869299905383682611063374747752091585836452902373843865043412096365874638466683035848817858586173172058756256354758712684819253211761289032789542371351760915771791997388241121078055468403109260493642435791152671979552597191217179672328555740595434990908530985477314228867209314472001848844089467987561661918366232980944933533
q3 = 66208618374366130551979192465001581263127328176551695213970812805980115496523825511250542987452691413485117902772315362811067501379171731387904074565035353566976164797769439898266222919741874340315356585585077141595328441423323822407738375537476582506440045835592730211502035261968878999959340204806442390319739977816872969200022096331677277225467021553564212725120939434924481787524609852608476848761521446441776154400518315701988027274150425936061679275540502720782853648148897480117033152064922234451671636288396704170234613549011854618414776342798740690128675106027908639984431432591397555541420243824539205614036979987830125678
'''
P = getPrime(1024)
Q = getPrime(1024)
N = P * Q
E = 65537
lcm = gmpy2.lcm(P-1, Q-1)
e1 = gmpy2.invert(p1, lcm)
e2 = gmpy2.invert(r1, lcm)
m = bytes_to_long(flag)
c = pow(m, E, N)print(lcm)
print(c)
print(N)
'''
lcm = 4292158730589770192682795435047249488185453170529228019750042608688907718268448193363838203887391025871515871000364259326343790645215256385842265899206372365402431198699714374850409466996627163968391249416054093529090485677808301343590811445080871279796162536469847469761747058736980603093722710824453312207182881241846080117790728778291633761198069016865260030288832065807438020772711645648333908622890343009942617559434851450007195025869850769670769715654662127278293639938359741401336592219730356884542179574372134014927006215640945952229142436595334916765255426954857520777553915330597952622785359222832224632624
c = 4288727484183191191687364666620023549392656794153112764357730676861570386983002380982803054964588111708662498647767438881892355599604826306427809017097724346976778230464708540600157055782723189971534549543664668430013171469625043063261219462210251726207552819381767396148632877168530609902046293626355744288863460554297860696918890189350721960355460410677203131993419723440382095665713164422367291153108363066159712951217816814873413423853338021627653555202253351957999686659021298525147460016557904084617528199284448056532965033560516083489693334373695545423561715471204868795248569806148395196572046378679014697206
N  = 17168634922359080770731181740188997952741812682116912079000170434755630873073792773455352815549564103486063484001457037305375162580861025543369063596825489461609724794798857499401637867986508655873564997664216374116361942711233205374363245780323485119184650145879389879046988234947922412374890843297813248828996855478005656041814919367820336728271583686844991928889831691815821365423570311291064846736832327637944358854661523107817781673029406341843040857813841671405147146887291204140157388049394514390098066284975682117038362207142272098796924412602725857521665773622056312191400612944442008222587867782281556388669
'''

          这道题纯吓人,因为密文跟p3,q3没关系。所以我们不需要用到它。注意的是,这里phi用lcm来表示了。

d = primefac.modinv(E, lcm)
m = pow(c, d, n)
primt(long_to_bytes(m))

          获得FLAG{h3ll0_wo21d!}

三、总结

          在这里,涵盖了大部分的模数分解法的题目做法。我们分析了如何判断以及尝试的优先级。如何根据代码报错,进行实时的调整、排错。

这篇关于RSA攻击:模数分解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/2691

相关文章

速盾高防cdn是怎么解决网站攻击的?

速盾高防CDN是一种基于云计算技术的网络安全解决方案,可以有效地保护网站免受各种网络攻击的威胁。它通过在全球多个节点部署服务器,将网站内容缓存到这些服务器上,并通过智能路由技术将用户的请求引导到最近的服务器上,以提供更快的访问速度和更好的网络性能。 速盾高防CDN主要采用以下几种方式来解决网站攻击: 分布式拒绝服务攻击(DDoS)防护:DDoS攻击是一种常见的网络攻击手段,攻击者通过向目标网

研究人员在RSA大会上演示利用恶意JPEG图片入侵企业内网

安全研究人员Marcus Murray在正在旧金山举行的RSA大会上公布了一种利用恶意JPEG图片入侵企业网络内部Windows服务器的新方法。  攻击流程及漏洞分析 最近,安全专家兼渗透测试员Marcus Murray发现了一种利用恶意JPEG图片来攻击Windows服务器的新方法,利用该方法还可以在目标网络中进行特权提升。几天前,在旧金山举行的RSA大会上,该Marcus现场展示了攻击流程,

特征值分解(EVD)和奇异值分解(SVD)—应用于图片压缩

特征值分解(EVD)和奇异值分解(SVD)—应用于图片压缩 目录 前言 一、特征值分解 二、应用特征值分解对图片进行压缩 三、矩阵的奇异值分解 四、应用奇异值分解对图片进行压缩 五、MATLAB仿真代码 前言         学习了特征值分解和奇异值分解相关知识,发现其可以用于图片压缩,但网上没有找到相应代码,本文在学习了之后编写出了图片压缩的代码,发现奇异值分

Web安全之XSS跨站脚本攻击:如何预防及解决

1. 什么是XSS注入 XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的Web安全漏洞,通过注入恶意代码(通常是JavaScript)到目标网站的网页中,以此在用户浏览网页时执行。攻击者可以通过XSS获取用户的敏感信息(如Cookie、会话令牌)或控制用户浏览器的行为,进而造成信息泄露、身份冒用等严重后果。 2. XSS攻击类型 2.1 存储型XSS 存储型XS

【前端安全】浅谈XSS攻击和防范

定义 XSS是跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。 恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。 分类 大分类小分类原理非存储DOM型① 不需要经过服务器

新型 RAMBO 侧信道攻击通过 RAM 无线电波泄露数据

内盖夫本·古里安大学的研究人员发现了一种从隔离系统中泄露敏感数据的方法。 引入了一种称为 RAMBO(基于 RAM 的电磁隐蔽通道)的新型攻击技术。 该攻击利用计算机 RAM 产生的电磁辐射,使攻击者能够窃取加密密钥、密码、生物特征数据和文件等信息。 即使在系统与外部网络物理隔离的环境中,这种攻击也能实现。 信息泄露速度达 7.5 kB/分钟 该研究由 Morde

DDoS对策是什么?详细解说DDoS攻击难以防御的理由和对策方法

攻击规模逐年增加的DDoS攻击。据相关调查介绍,2023年最大的攻击甚至达到了700Gbps。 为了抑制DDoS攻击的危害,采取适当的对策是很重要的。 特别是在网站显示花费时间或频繁出现504错误的情况下,可能已经受到了DDoS攻击,需要尽早采取对策。 本文将介绍受到DDoS攻击时的事件、受害内容和作为DDoS对策有效的三种服务。 到底什么是DDoS攻击? 理解事件、手段和损害 D

连分数因子分解法——C语言实现

参考网址:连分数分解法寻找整数的因子(Python)-CSDN博客 大数运算:C语言实现 大数运算 加减乘除模运算 超详细_64编程 加减乘除取模 复杂运算-CSDN博客 ‌连分数因子分解法‌是一种用于大整数因子分解的算法,它是计算数论中的一个重要方法。连分数因子分解法通过寻找x2≡y2 (mod p)x2≡y2 (mod p)的形式来分解N。具体来说,这种方法涉及到计算N的简单连分数展开,并

时序预测|变分模态分解-双向时域卷积-双向门控单元-注意力机制多变量时间序列预测VMD-BiTCN-BiGRU-Attention

时序预测|变分模态分解-双向时域卷积-双向门控单元-注意力机制多变量时间序列预测VMD-BiTCN-BiGRU-Attention 文章目录 一、基本原理1. 变分模态分解(VMD)2. 双向时域卷积(BiTCN)3. 双向门控单元(BiGRU)4. 注意力机制(Attention)总结流程 二、实验结果三、核心代码四、代码获取五、总结 时序预测|变分模态分解-双向时域卷积

网络安全与恶意攻击:如何应对?

引言 随着技术的发展,我们的生活越来越依赖于网络。但是,这也暴露了我们的系统对各种网络威胁的脆弱性。无论是个人还是企业,网络安全都成为了我们不能忽视的话题。 网络威胁的类型 网络威胁主要有以下几种: 网络钓鱼攻击:这是一种试图通过冒充合法实体来欺骗用户提供敏感信息(例如,密码或信用卡信息)的攻击。 **恶意软件:**恶意软件是设计用来破坏、损坏或者非法获取访问权限的软件。其中包括病