ctf.show RSA入门题目题解若干

本文介绍了RSA加密算法在不同情况下的解密方法,包括利用e的特殊值、n的分解、n的公因数、e的乘积、p和q的接近性以及p的小数值。通过实例展示了如何利用这些特点进行解密,从而揭示了RSA安全性的重要性和解密的复杂性。

最近在补习RSA相关知识,做了一些题目,发现有很多套路,于是略作整理。


babyrsa 普通rsa解密

题目给了e、p、q,还给了c

e = 65537
p = 104046835712664064779194734974271185635538927889880611929931939711001301561682270177931622974642789920918902563361293345434055764293612446888383912807143394009019803471816448923969637980671221111117965227402429634935481868701166522350570364727873283332371986860194245739423508566783663380619142431820861051179
q = 140171048074107988605773731671018901813928130582422889797732071529733091703843710859282267763783461738242958098610949120354497987945911021170842457552182880133642711307227072133812253341129830416158450499258216967879857581565380890788395068130033931180395926482431150295880926480086317733457392573931410220501
c = 4772758911204771028049020670778336799568778930072841084057809867608022732611295305096052430641881550781141776498904005589873830973301898523644744951545345404578466176725030290421649344936952480254902939417215148205735730754808467351639943474816280980230447097444682489223054499524197909719857300597157406075069204315022703894466226179507627070835428226086509767746759353822302809385047763292891543697277097068406512924796409393289982738071019047393972959228919115821862868057003145401072581115989680686073663259771587445250687060240991265143919857962047718344017741878925867800431556311785625469001771370852474292194

思路:根据两个质数p、q可以算出n和φ(n),从而算出解密参数d(d为e在模φ(n)下的逆元),由密文c、解密参数d、还有素数乘积n可以算出明文m。

解密代码

import libnum
from Crypto.Util.number import long_to_bytes

e = 65537
p = 104046835712664064779194734974271185635538927889880611929931939711001301561682270177931622974642789920918902563361293345434055764293612446888383912807143394009019803471816448923969637980671221111117965227402429634935481868701166522350570364727873283332371986860194245739423508566783663380619142431820861051179
q = 140171048074107988605773731671018901813928130582422889797732071529733091703843710859282267763783461738242958098610949120354497987945911021170842457552182880133642711307227072133812253341129830416158450499258216967879857581565380890788395068130033931180395926482431150295880926480086317733457392573931410220501
c = 4772758911204771028049020670778336799568778930072841084057809867608022732611295305096052430641881550781141776498904005589873830973301898523644744951545345404578466176725030290421649344936952480254902939417215148205735730754808467351639943474816280980230447097444682489223054499524197909719857300597157406075069204315022703894466226179507627070835428226086509767746759353822302809385047763292891543697277097068406512924796409393289982738071019047393972959228919115821862868057003145401072581115989680686073663259771587445250687060240991265143919857962047718344017741878925867800431556311785625469001771370852474292194

# 根据p、q可以算出n和φ(n)
n = p * q
phi_n = (p-1)*(q-1)

# 根据e和φ(n)可以算出d
d = libnum.invmod(e, phi_n)

# 根据c、d、n可以解密出明文m
m = pow(c, d, n)

# 数字转字节序列
print(long_to_bytes(m))

得到明文:flag{b4by_R5A}


easyrsa1 n太小可以直接分解

题目给了e、n,还有密文c

e = 65537
n = 1455925529734358105461406532259911790807347616464991065301847
c = 69380371057914246192606760686152233225659503366319332065009

思路:我们缺少参数p、q,也就缺少φ(n),但是我们发现n这个数比较小,很有可能在可接受时间内被现有计算机分解质因数出两个素数p、q

我们使用yafu工具分解质因数

yafu-x64.exe factor(1455925529734358105461406532259911790807347616464991065301847)

很快分解质因数成功得到2个质数

P31 = 1212112637077862917192191913841
P31 = 1201147059438530786835365194567

有了2个质数p、q就好办了,就可以算出φ(n)了

解密代码

import libnum
from Crypto.Util.number import long_to_bytes

e = 65537
n = 1455925529734358105461406532259911790807347616464991065301847
c = 69380371057914246192606760686152233225659503366319332065009

# p和q是我们发现n比较小于是果断用工具分解质因数得到的
p = 1212112637077862917192191913841
q = 1201147059438530786835365194567


n = p * q
phi_n = (p-1)*(q-1)
d = libnum.invmod(e, phi_n)

m = pow(c, d, n)
print(long_to_bytes(m))

得到明文:flag{fact0r_sma11_N}


easyrsa2 两个n有公因数

题目给了我们2组e、n、c,而且n是比较大的,如果不是特殊的n不太好分解~~,但是经观察发现这两组参数中的e参数是一样的(貌似没啥用)。~~

将大数n分解为2个素数是困难问题,如果不是特殊的n不太好办,但是求2个大数的最大公因子是简单问题,欧几里得算法就可以办到。

我们猜测给的这两个大数n1和n2是不是有不等于1的最大公因子呢?

由于n1=p1*q1n2=p2*q2,如果n1和n2有一个公因子p,即p=p1=p2,那么我们就可以用欧几里得算法快速求出两个数n1、n2的最大公因子p,于是q1和q2也可以通过q1=n1/pq2=n2/p得到了。

解密脚本

import libnum
from Crypto.Util.number import long_to_bytes

e = 65537
n1 = 23686563925537577753047229040754282953352221724154495390687358877775380147605152455537988563490716943872517593212858326146811511103311865753018329109314623702207073882884251372553225986112006827111351501044972239272200616871716325265416115038890805114829315111950319183189591283821793237999044427887934536835813526748759612963103377803089900662509399569819785571492828112437312659229879806168758843603248823629821851053775458651933952183988482163950039248487270453888288427540305542824179951734412044985364866532124803746008139763081886781361488304666575456680411806505094963425401175510416864929601220556158569443747
c1 = 1627484142237897613944607828268981193911417408064824540711945192035649088104133038147400224070588410335190662682231189997580084680424209495303078061205122848904648319219646588720994019249279863462981015329483724747823991513714172478886306703290044871781158393304147301058706003793357846922086994952763485999282741595204008663847963539422096343391464527068599046946279309037212859931303335507455146001390326550668531665493245293839009832468668390820282664984066399051403227990068032226382222173478078505888238749583237980643698405005689247922901342204142833875409505180847943212126302482358445768662608278731750064815

# e = 65537
n2 = 22257605320525584078180889073523223973924192984353847137164605186956629675938929585386392327672065524338176402496414014083816446508860530887742583338880317478862512306633061601510404960095143941320847160562050524072860211772522478494742213643890027443992183362678970426046765630946644339093149139143388752794932806956589884503569175226850419271095336798456238899009883100793515744579945854481430194879360765346236418019384644095257242811629393164402498261066077339304875212250897918420427814000142751282805980632089867108525335488018940091698609890995252413007073725850396076272027183422297684667565712022199054289711
c2 = 2742600695441836559469553702831098375948641915409106976157840377978123912007398753623461112659796209918866985480471911393362797753624479537646802510420415039461832118018849030580675249817576926858363541683135777239322002741820145944286109172066259843766755795255913189902403644721138554935991439893850589677849639263080528599197595705927535430942463184891689410078059090474682694886420022230657661157993875931600932763824618773420077273617106297660195179922018875399174346863404710420166497017196424586116535915712965147141775026549870636328195690774259990189286665844641289108474834973710730426105047318959307995062

# 尝试获取n1和n2的不为1的最大公因子
p = libnum.gcd(n1, n2)
if p==1:
    exit("n1和n2没有不为1的最大公因子")

# 这里要用 // 使得q1、q2的类型为整数,不然浮点数的话后边的运算似乎会超慢
q1 = n1 // p
q2 = n2 // p

phi_n1 = (p-1)*(q1-1)
phi_n2 = (p-1)*(q2-1)
d1 = libnum.invmod(e, phi_n1)
d2 = libnum.invmod(e, phi_n2)

m1 = pow(c1, d1, n1)
m2 = pow(c2, d2, n2)

print
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值