声明:本篇内容集合了各处的博客,资料,视频,可能与已经发布的各类资料有所相同,正常的,这篇类似于收集型的文章,算是留给个人看以及和同行分享的知识,如果内容有雷同,说不定就是我在别的地方看到过加进来了。
首先我们需要知道RSA的基本原理
不过在了解基本原理之前我们在这里先介绍几个相关的数学概念
1.欧拉函数φ(n)
欧拉函数等于(p-1)×(q-1)
目的是求小于x并且和x互质的数的个数
公式为:φ(n)=(p-1)×(q-1)
2.模反元素d
所谓“”模反元素“”,就是指有一个整数d,可以使得ed被φ(n)除的余数为1
即 de=1 (mod φ(n))
或者 de-1=kφ(n)
RSA加密过程
第一步,随机选择两个不相等的质数p和q,
例如选择 61 和53
第二步,计算p和q的乘积n
n=61×53=3233
第三步,计算n的欧拉函数
利用公式φ(n)=(p-1)×(q-1)
的φ(3233)=60×52=3120,即,小于3233,并且和3233互质的数有3120个
第四步,随机选择一个整数e,条件时1<e<φ(n) ,,且e与φ(n)互质
在e到3120之间,随机选择了17.(实际应用中经常选择65537)
第五步,计算e对φ(n)的模反元素d
已知e=17,φ(n)=3120,17x+3120y=1
算出一组整数解为(x,y)=(2753,-15),即d=2753
第六步,将n和e封装成公钥,n和d分装成私钥
n=3233,e=17,d=2753,所以公钥就是(3233,17),私钥就是(3233,2753)
例题1
我们先来看一道最基础的题目
[buuctf]RSA
很直接了当的告诉你了p,q,e,让你求d
这里要先介绍gmpy2库的一个方法:
invert(e,n)
invert(e,n) 求逆元 de=1 mod n
d = gmpy2.invert(e,(p-1)(q-1))
即意为将1 mod (p-1)×(q-1) 然后再除以e,放在下文中就是4511490×473398607160然后除以17,当然你直接写
a=4511490473398607160/17
会得到1.2563135777742755e+17,因为正常除法运算的精度不够,所以我们一般情况下都需要借助gmpy2这个库来实现RSA的运算
这题我们根据前面介绍过的RSA的原理就可以解答,这题考察的就是最简单的l利用公式求模反元素d
我们根据模范元素的公式de=1 mod n,,并且n=(p-1)*(q-1)
import gmpy2
p=473398607161
q=4511491
e=17
d = gmpy2.invert(e,(q-1)*(p-1))
print (d)
例题2
[buuctf]rsarsa
题目:
Math is cool! Use the RSA algorithm to decode the secret message, c, p, q, and e are parameters for the RSA algorithm.
p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
Use RSA to find the secret message
跟上一题相比除了数字变大了之外,还多给了一个c,这个c呢,是明文的意思,做这一题之前我们还需要知道两个东西
一个是c代表了什么,c代表了明文,我们知道公钥为(e,n),密钥为(n,d),那么明文,就是密文的e次方然后mod n
也就是密文,乘上我们随机选取的这个位于1和,欧拉函数之间的这个数e的次幂,再对n取余,就能得到密文,
同时,我们知道了RSA中还存在一个名为密文的东西,密文我们用m来代表,也就是m是明文的d次幂然后对n取余,就能得到明文,而题目教我们求密文,并且已经告诉了我们明文,想必应该就是用下面那张图的公式来求取答案了
另外一个一个是pow函数,pow(m,e,n),意为求c^d mod n,也就是c的d次求n求余
脚本如下,利用了我们刚才所说的pwo函数,最后print (pow(c,d,n)),也就是输出的是c^d mod n,也就是已知密文,求明文的公式,
而前面的准备工作由,利用模反元素的公式求n
所以这题我们总结如下
我们所拥有的的条件有:已知,p,.q,e和明文c
我们所要求的结果是:密文m
第一步,通过模反元素的公式de=1 mod n求得d
第二步,通过已知明文和模范元素还有n求能求密文m的公式m=c^d mod n 求得m的结果
import gmpy2
p=9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q=11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e=65537
c=83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
d = gmpy2.invert(e,(q-1)*(p-1))
n=p*q
print (pow(c,d,n))
例题3 [buu]RsaRoll
RSA roll!roll!roll!
Only number and a-z
(don’t use editor
which MS provide)
{920139713,19}
704796792
752211152
274704164
18414022
368270835
483295235
263072905
459788476
483295235
459788476
663551792
475206804
459788476
428313374
475206804
459788476
425392137
704796792
458265677
341524652
483295235
534149509
425392137
428313374
425392137
341524652
458265677
263072905
483295235
828509797
341524652
425392137
475206804
428313374
483295235
475206804
459788476
306220148
看到这个题目,我们{920139713,19}第一眼就可以看出这是密钥,我们根据前文介绍的,n和e是公钥,n和d是私钥可以知道为什么不会是公钥么,因为d是模范元素,在n这么大的情况下,显然是不会只有19那么小的,所以这只能是密钥(当然你也可以两种都试试,反正在这题的情况下不麻烦)
知道了密钥之后,这里要介绍一个东西,那就是暴力分解n,要知道,我们求解RSA,有种最快的方法,那就是将n暴力分解为p,q,再知道n和p,q,还有e的情况下,d显然可以求得,而这时我们只要知道一个明文,就可以求解它的密文,那么RSA基本上的东西我们就算都知道了
然后有这么一个网站
http://www.factordb.com/
放入然后分解,得到18443和49891两个数,加上已经拥有的19然后我们就可以计算得到d=96849619
import gmpy2
p = 18443
q = 49891
e = 19
n = (p-1)*(q-1)
d = gmpy2.invert(e,n)
print("p=%s,q=%s,e=%s"%(p,q,e))
print(d)
d=96849619
这里介绍一个函数方法,叫做split即分割
split(str="", num=string.count(str)).
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。默认为 -1, 即分隔所有。
第一个参数为以书面分割,例如第一个参数为逗号,则以所有逗号为分界线分割所有字符,如果为空,则默认以空格,换行符,制表符的等为分界线,
第二个参数为分割次数,默认分割所有,所以下文的split()的意思就是,以空格等分割所有字符
import gmpy2
p = 18443
q = 49891
e = 19
n = 920139713
d = 96849619
c="""
704796792
752211152
274704164
18414022
368270835
483295235
263072905
459788476
483295235
459788476
663551792
475206804
459788476
428313374
475206804
459788476
425392137
704796792
458265677
341524652
483295235
534149509
425392137
428313374
425392137
341524652
458265677
263072905
483295235
828509797
341524652
425392137
475206804
428313374
483295235
475206804
459788476
306220148
"""
result=""
c_list=c.split()
for i in c_list:
result+=chr(pow(int(i),d,n)) """将每一行数字的d次幂然后mod n ,然后放到result里,第一行就是704796792的96849619次 对920139713取余,得到102然后将这个数字视为asc码,然后转换成对应的字符串f"""
print(result)
答案:flag{13212je2ue28fy71w8u87y31r78eu1e2}
第四题
[RoarCTF2019]RSA
https://blog.csdn.net/weixin_44110537/article/details/107349428
直接用大数分解得到p,和q,这时候不知道e,用爆破的,得到e=65537
p=842868045681390934539739959201847552284980179958879667933078453950968566151662147267006293571765463137270594151138695778986165111380428806545593588078365331313084230014618714412959584843421586674162688321942889369912392031882620994944241987153078156389470370195514285850736541078623854327959382156753458569
q=139916095583110895133596833227506693679306709873174024876891023355860781981175916446323044732913066880786918629089023499311703408489151181886568535621008644997971982182426706592551291084007983387911006261442519635405457077292515085160744169867410973960652081452455371451222265819051559818441257438021073941183
c=41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128
import gmpy2
e=65537
d=gmpy2.invert(e,(p-1)*(q-1))
import binascii
print(binascii.unhexlify(hex(gmpy2.powmod(c,d,p*q))[2:]))
binascii.unhexlify(hexstr)