RSA

RSA加密

欧拉定理

若n为素数欧拉(n)=n-1;

e与欧拉(n)互质 公钥e,n 私钥d,n

M为明文,C为密文;

M^e mod n=C

C^d mod n =M

ed=1(mod欧拉(n))

d为模反元素计算公式,d=gmpy2.invert(e,(p-1)*(q-1))

n=p*q ,欧拉n=(p-1)*(q-1)

已知dp,dq,p,q,c

dp=d%(p-1)

dq=d%(q-1)

rsa解密详解以及脚本.
rsa解密详解以及脚本;

gmpy2常见函数使用

1.初始化大整数

1
2
3
import gmpy2
gmpy2.mpz(909090)
result:mpz(909090)

2.求大整数a,b的最大公因数

1
2
3
import gmpy2
gmpy2.gcd(6,18)
result:mpz(6)

3.求大整数x模m的逆元y

1
2
3
4
import gmpy2
#4*6 ≡ 1 mod 23
gmpy2.invert(4,23)
result:mpz(6)

4.检验大整数是否为偶数

1
2
3
4
5
6
import gmpy2
gmpy2.is_even(6)
result:True
import gmpy2
gmpy2.is_even(7)
result:False

5.检验大整数是否为奇数

1
2
3
4
5
6
import gmpy2
gmpy2.is_odd(6)
result:False
import gmpy2
gmpy2.is_odd(7)
result:True

6.检验大整数是否为素数

1
2
3
import gmpy2
gmpy2.is_prime(5)
result:True

7.求大整数x开n次根

1
2
3
import gmpy2
gmpy2.iroot(81,2)
result:(mpz(9),True)

8.求大整数x的y次幂模m取余

1
2
3
4
import gmpy2
#2^4 mod 5
gmpy2.powmod(2,4,15)
result:mpz(1)

libnum库
十进制转字符串 libnum.n2s(j)

已知p, q, e,求d。

1
2
3
4
5
6
7
import gmpy2
p = 447685307
q = 2037
e = 17
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
print(d)

已知(p, q, e,c),求m。

1
2
3
4
5
6
7
8
9
10
11
import gmpy2
p=447685307
q=2037
e=17
c=704796792

phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,p*q)

print(m)

已知p,q,dp,dq,c,求m

buu RSA1

所需要求的值:

1
2
3
4
5
p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229 
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852

(1)计算q逆模q1;
(2)计算m1为c的dp次方再对p求模
(3)计算m2为c的dq次方再对q求模
(4)m = ((((m2 - m1) * p1) % q) * p + m2) % n;

1
2
3
4
5
6
7
8
9
10
11
12
13
import gmpy2
import libnum
p =
q =
dp =
dq =
c =
n = p * q
m1 = pow(c, dp, p)
m2 = pow(c, dq, q)
p1 = gmpy2.invert(q, p)
m = ((((m2 - m1) * p1) % q) * p + m2) % n
print libnum.n2s(m)

(4条消息) BUUCTF RSA题目全解1_buuctf rsa1_宁嘉的博客-CSDN博客

已知(e,dp, n, c),求m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import binascii
e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751

for i in range(1,e):
if (e*dp-1)%i == 0 and n%((e*dp-1)//i+1)==0:
q = n//((e*dp-1)//i+1)
phi = (q-1)*((e*dp-1)//i)
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,n)

print(binascii.unhexlify(hex(m)[2:]))
1
2
3
4
5
c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
e1=11187289
c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2=9647291

已知(n, e1, e2,c1,c2),求m。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import gmpy2
import binascii

n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e1 = 11187289
e2 = 9647291

s = gmpy2.gcdext(e1,e2)
a = s[1]
b = s[2]

if a<0:
a = -a
c1 = gmpy2.invert(c1,n)
else:
b = -b
c2 = gmpy2.invert(c2,n)

m = (gmpy2.powmod(c1,a,n)*gmpy2.powmod(c2,b,n))%n

print(binascii.unhexlify(hex(m)[2:]))

已知( e,n1,c1,n2,c2),求m。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import gmpy2
import binascii

e = 65537
n1 = 23686563925537577753047229040754282953352221724154495390687358877775380147605152455537988563490716943872517593212858326146811511103311865753018329109314623702207073882884251372553225986112006827111351501044972239272200616871716325265416115038890805114829315111950319183189591283821793237999044427887934536835813526748759612963103377803089900662509399569819785571492828112437312659229879806168758843603248823629821851053775458651933952183988482163950039248487270453888288427540305542824179951734412044985364866532124803746008139763081886781361488304666575456680411806505094963425401175510416864929601220556158569443747
c1 = 1627484142237897613944607828268981193911417408064824540711945192035649088104133038147400224070588410335190662682231189997580084680424209495303078061205122848904648319219646588720994019249279863462981015329483724747823991513714172478886306703290044871781158393304147301058706003793357846922086994952763485999282741595204008663847963539422096343391464527068599046946279309037212859931303335507455146001390326550668531665493245293839009832468668390820282664984066399051403227990068032226382222173478078505888238749583237980643698405005689247922901342204142833875409505180847943212126302482358445768662608278731750064815

n2 = 22257605320525584078180889073523223973924192984353847137164605186956629675938929585386392327672065524338176402496414014083816446508860530887742583338880317478862512306633061601510404960095143941320847160562050524072860211772522478494742213643890027443992183362678970426046765630946644339093149139143388752794932806956589884503569175226850419271095336798456238899009883100793515744579945854481430194879360765346236418019384644095257242811629393164402498261066077339304875212250897918420427814000142751282805980632089867108525335488018940091698609890995252413007073725850396076272027183422297684667565712022199054289711
c2 = 2742600695441836559469553702831098375948641915409106976157840377978123912007398753623461112659796209918866985480471911393362797753624479537646802510420415039461832118018849030580675249817576926858363541683135777239322002741820145944286109172066259843766755795255913189902403644721138554935991439893850589677849639263080528599197595705927535430942463184891689410078059090474682694886420022230657661157993875931600932763824618773420077273617106297660195179922018875399174346863404710420166497017196424586116535915712965147141775026549870636328195690774259990189286665844641289108474834973710730426105047318959307995062

p = gmpy2.gcd(n1,n2)
q = n1 // p
phi = (p-1)*(q-1)

d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c1,d,n1)

print(binascii.unhexlify(hex(m)[2:]))

已知(p+q,p-q, e,c),求m。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import gmpy2
import libnum
e=16300321

a=21350430512059560135536506725886192791652921782342757815537127809818896096167861777432862988721624947176730121127946250044713187944377040826978092675745896

b=1553262765888789433201396543987134442184487100865056152409628170591088051337453032936901834118611146414395714768350794090251064953913440485676167006809370

c=54505145716437017236783669089525458569996474667747952435007039609752579283598944353442923680602360632342975079757448484712025793719352475806343163818881133707590318426509468029706897810742965068881431810720947035196632950024324040788801133194474150406380691624739115334015886740557921339305357167098392744905

p = (a+b)//2
q = (a-b)//2

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

m = gmpy2.powmod(c,d,p*q)
print(libnum.n2s(m))

已知(e,n,c),求m。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import gmpy2
import binascii

e = 65537
n = 1455925529734358105461406532259911790807347616464991065301847
c = 69380371057914246192606760686152233225659503366319332065009
p = 1201147059438530786835365194567
q = 1212112637077862917192191913841

phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,n)

print(binascii.unhexlify(hex(m)[2:]))

已知(e,n,c),求m。

e比较小时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import binascii

e = 3
n = 18970053728616609366458286067731288749022264959158403758357985915393383117963693827568809925770679353765624810804904382278845526498981422346319417938434861558291366738542079165169736232558687821709937346503480756281489775859439254614472425017554051177725143068122185961552670646275229009531528678548251873421076691650827507829859299300272683223959267661288601619845954466365134077547699819734465321345758416957265682175864227273506250707311775797983409090702086309946790711995796789417222274776215167450093735639202974148778183667502150202265175471213833685988445568819612085268917780718945472573765365588163945754761
c = 150409620528139732054476072280993764527079006992643377862720337847060335153837950368208902491767027770946661

i = 0
while True:
if gmpy2.iroot((c+i*n),3)[1] == True:
m = gmpy2.iroot((c+i*n),3)[0]
break
i += 1

print(binascii.unhexlify(hex(m)[2:]))

模不互素

当存在两个公钥的 N 不互素时,我们显然可以直接对这两个数求最大公因数,然后直接获得 p,q,进而获得相应的私钥。

P高位泄露

[CISCN 2021初赛]rsa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from flag import text,flag
import md5
from Crypto.Util.number import long_to_bytes,bytes_to_long,getPrime

assert md5.new(text).hexdigest() == flag[6:-1]

msg1 = text[:xx]
msg2 = text[xx:yy]
msg3 = text[yy:]

msg1 = bytes_to_long(msg1)
msg2 = bytes_to_long(msg2)
msg3 = bytes_to_long(msg3)

p1 = getPrime(512)
q1 = getPrime(512)
N1 = p1*q1
e1 = 3
print pow(msg1,e1,N1)
print (e1,N1)//第一部分低加密指数攻击

p2 = getPrime(512)
q2 = getPrime(512)
N2 = p2*q2
e2 = 17
e3 = 65537
print pow(msg2,e2,N2)
print pow(msg2,e3,N2)
print (e2,N2)
print (e3,N2)//共模攻击

p3 = getPrime(512)
q3 = getPrime(512)
N3 = p3*q3
print pow(msg3,e3,N3)
print (e3,N3)
print p3>>200 //p高位泄露类型

解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Sage
from sage.all import *
n = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
p4 = 7117286695925472918001071846973900342640107770214858928188419765628151478620236042882657992902
#p去0的剩余位
e = 65537
pbits = 512
kbits = pbits - p4.nbits()
print(p4.nbits())
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4)
if roots:
p = p4+int(roots[0])
print("n: "+str(n))
print("p: "+str§)
print("q: "+str(n//p))

sictf 的密码题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

from Crypto.Util.number import *
from flag import flag
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 65537
leak = p >> 230
m = bytes_to_long(flag)
c = pow(m,e,n)
print(n)
print(leak)
print(c)
'''
114007680041157617250208809154392208683967639953423906669116998085115503737001019559692895227927818755160444076128820965038044269092587109196557720941716578025622244634385547194563001079609897387390680250570961313174656874665690193604984942452581886657386063927035039087208310041149977622001887997061312418381
6833525680083767201563383553257365403889275861180069149272377788671845720921410137177
87627846271126693177889082381507430884663777705438987267317070845965070209704910716182088690758208915234427170455157948022843849997441546596567189456637997191173043345521331111329110083529853409188141263211030032553825858341099759209550785745319223409181813931086979471131074015406202979668575990074985441810
'''

一般情况下需要已知286位才能求解512的p

但是把small_roots(epsilon = 0.01)改动epsilon参数为0.01可以在已知264位的情况下求解p

题目给出高282,修改参数epsilon即可求解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Sage
from sage.all import *
n = 114007680041157617250208809154392208683967639953423906669116998085115503737001019559692895227927818755160444076128820965038044269092587109196557720941716578025622244634385547194563001079609897387390680250570961313174656874665690193604984942452581886657386063927035039087208310041149977622001887997061312418381
p4 = 6833525680083767201563383553257365403889275861180069149272377788671845720921410137177
#p去0的剩余位
e = 65537
pbits = 512
kbits = pbits - p4.nbits()
print(p4.nbits())
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4,epsilon=0.01)
if roots:
p = p4+int(roots[0])
print("n: "+str(n))
print("q: "+str(n//p))

p^2+q^2

例题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import *
from gmpy2 import *
from secret import flag
p = getPrime(1024)
q = getPrime(200)

a = p**2 + q**2
n = p * q
e1 = getPrime(16)
e2 = next_prime(e1)
m = bytes_to_long(flag)
c1 = powmod(m,e1,n)
c2 = powmod(m**3,e2,3*n)

print('a =', a)
print('c1 =', c1)
print('c2 =', c2)

'''
a = 23804021940078676408342301332036892900004728136480076479530219752065125327318821647722459216095770264965388973551323635311313178838670860487788476788686756050157264721772586844596306406576857878507037529439070526513923394974678433717664180257965624133033383511215139076867891548866207158515487182813656668091870588002638518245252590786003914393372830494390833657940568569618842104970029260363695053572749495893999945220493935637334868029460448282514843103145795102173534495304156971490358608124680851055950154432367509652612855903019752959349069234185596982394068554146096092741880878895682860091022727772496856721290
c1 = 75949211970645260477840809230795170598275394663655585446502049744151634977806266592064437936389888280642329073167371358021391264606028082728274944584341647324957857195053188220196244561623697425292916511744852569537275299008074069250282222480373555169325242455879869868679935977005580843853804599341730525546675515324718058489296906319060874296111833437083796029771812
c2 = 77907941155376849046818020584594846942386293571953448410760364023962818506838837521412252753647936913064982141652362831680077554268552176063108954360620095019160785058740575077744544616439692739387312706279917959252426192939648962492950940347253817951644007140862267776520611944302335981903665518644840891111449931544355548130487697653008605945892957382219567188182572
'''

将已知量p 2 + q 2 p^2 + q ^2p
2
+q
2
直接开方即可得到较大的数p pp,因为开方会使得含有较小的数q 2 q^2q
2
的部分丢失,剩余的正好使p 2 p^2p
2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import *
from tqdm import tqdm
import gmpy2

a = 23804021940078676408342301332036892900004728136480076479530219752065125327318821647722459216095770264965388973551323635311313178838670860487788476788686756050157264721772586844596306406576857878507037529439070526513923394974678433717664180257965624133033383511215139076867891548866207158515487182813656668091870588002638518245252590786003914393372830494390833657940568569618842104970029260363695053572749495893999945220493935637334868029460448282514843103145795102173534495304156971490358608124680851055950154432367509652612855903019752959349069234185596982394068554146096092741880878895682860091022727772496856721290
c1 = 75949211970645260477840809230795170598275394663655585446502049744151634977806266592064437936389888280642329073167371358021391264606028082728274944584341647324957857195053188220196244561623697425292916511744852569537275299008074069250282222480373555169325242455879869868679935977005580843853804599341730525546675515324718058489296906319060874296111833437083796029771812
c2 = 77907941155376849046818020584594846942386293571953448410760364023962818506838837521412252753647936913064982141652362831680077554268552176063108954360620095019160785058740575077744544616439692739387312706279917959252426192939648962492950940347253817951644007140862267776520611944302335981903665518644840891111449931544355548130487697653008605945892957382219567188182572

p = gmpy2.iroot(a, 2)[0]
q = gmpy2.iroot(a - p ** 2, 2)[0]
n = p * q
fai_n = (p - 1) * (q - 1)
for e in tqdm(range(2**16)):
try:
d = gmpy2.invert(e, fai_n)
m1 = pow(c1, d, n)
try:
print(long_to_bytes(m1).decode())
break
except:
continue
except:
continue

dp低位泄露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def getFullP(low_p, n):
R.<x> = PolynomialRing(Zmod(n), implementation='NTL')
p = x*2^512 + low_p
root = (p-n).monic().small_roots(X = 2^128, beta = 0.4)
if root:
return p(root[0])
return None

def phase4(low_d, n, c):
maybe_p = []
for k in range(1, 4):
p = var('p')
p0 = solve_mod([3*p*low_d == p + k*(n*p - p^2 - n + p)], 2^512)
maybe_p += [int(x[0]) for x in p0]
print(maybe_p)

for x in maybe_p:
P = getFullP(x, n)
if P: break

P = int(P)
Q = n // P

assert P*Q == n

d = inverse_mod(3, (P-1)*(Q-1))
print(hex(power_mod(c, d, n))[2:])



n = 92896523979616431783569762645945918751162321185159790302085768095763248357146198882641160678623069857011832929179987623492267852304178894461486295864091871341339490870689110279720283415976342208476126414933914026436666789270209690168581379143120688241413470569887426810705898518783625903350928784794371176183
c = 56164378185049402404287763972280630295410174183649054805947329504892979921131852321281317326306506444145699012788547718091371389698969718830761120076359634262880912417797038049510647237337251037070369278596191506725812511682495575589039521646062521091457438869068866365907962691742604895495670783101319608530
low_d = 787673996295376297668171075170955852109814939442242049800811601753001897317556022653997651874897208487913321031340711138331360350633965420642045383644955
phase4(low_d, n, c)

公钥指数e相关攻击

e与phi 不互素

1
2
3
4
5
6
7
8
9
e1 = 14606334023791426
p1 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1 = 130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
c1 = 11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248

e2 = 13813369129257838
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919

解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import gmpy2
from Crypto.Util.number import *
from libnum import *

e1 = 14606334023791426
e2 = 13813369129257838
p =
q1 =
q2 =
c1 =
c2 =

n1 = p*q1
n2 = p*q2

phi1 = (p-1)*(q1-1)
phi2 = (p-1)*(q2-1)

b = gmpy2.gcd(e1,e2)
a1 = e1//b
a2 = e2//b
bd1 = gmpy2.invert(a1,phi1)
bd2 = gmpy2.invert(a2,phi2)
m1 = pow(c1,bd1,n1)
m2 = pow(c2,bd2,n2)

c = solve_crt([m1, m2], [q1, q2])

n = q1 * q2
f = (q1 - 1) * (q2 - 1)

d2 = gmpy2.invert(7, f)
m = pow(c, d2, n)
msg = gmpy2.iroot(m, 2)[0]
print(long_to_bytes(msg).decode('utf-8'))

低加密指数(已知e,n,c)

e比较小时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import gmpy2
import binascii

e = 3
n =
c =

i = 0
while True:
if gmpy2.iroot((c+i*n),3)[1] == True:
m = gmpy2.iroot((c+i*n),3)[0]
break
i += 1

print(binascii.unhexlify(hex(m)[2:]))

低加密广播攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import libnum
import gmpy2


def rsa_gb_def(c, n, e):
m1 = libnum.solve_crt(c, n)
m, s = gmpy2.iroot(m1, e)
m = int(m)
return m

e = 17
n1 = 14628911682936716611458501697007036859460044243525290515096052103585430459755335375005202100114469571371360084664887335211277585652711111523095037589648375630146039444071400098427638768750755153219974194380355807078158427824557754939604018020265955042573660474772006646525311705184431094905718137297923127124517126579859336516891364853724635334011666814712424599592662398013241607855160919361308195967978220182785816761656927836373944699635667244275310680450562446433724968942835275279255823144471582249379035668825437133182865600026935116686574740844588839352146024513673500770611055698030333734066230166111140083923
n2 = 16756694748293603983474688536179571665757862433174984877308316444468003022266277794769268134195205510197588585566270416339902269736376811449830775290335951504698137924773942880807921752691668522662285163130340474205633998154849689387759453003838730282756734975490180702422176361373516245372635401939755527017589503572550811648345570775428936487145892225736625411540461653083957762795820510109891180906709827194217045059033312564525916136573856999724346161896146703174418039344166251503310869772735585554127509732135494936119159784702673291794381095696332128950979288440758815310482211285712819274848744478643590996499
n3 = 12023158079717019193506148537498877243668782424904061914991928068483879707115315968983829360560644394409575645736275352836086080024994045582242629571839276759393418303915955798990522990081795218822313146157773272844272865701134880180795342597049645358985187689813369428579614193015028249821853347208001645148169449968882591709833452960545988520048722323580338213590245476892223967673180144525106292453573842357322398199104132677638909964034937501684668442732786408572501007756270725934445316827054687741612177409932320532825182104820899546084015733164816993674100635828218335112393003462442685677115798304835391938681
c1 = 786426913645332991929803636719878643130489430090701482974255190570111407517277263761161970232982615374753982050075781017755721714929721429185828101898786972242994012456972241276851428750970754773002966788642795040933520662931514953660571657013642671173456750800960592586345219252277575624120271330470724245201080094330964145796872211627254805407394764183615099525852600855622089361965086460279057625205099471122036599934609091062009161119885692567925924978687256063116915630947838112126347748759078024890458539541208153526564434483654508834147071166870006117573542198238493913144419569943131642262575848786399020602
c2 = 14269311999815379511888097227418748728398011595172649708273598243317106830139061994801598925448165045032084910971094414749744701731066555194159863759072739031915833091715422787808666326235589236328864675164322734119047182014621724868200908222400504845559290620275973427127376594365043386362821355037781568524903149101953873768462097165128186788759111090267131443645126715520994688945363059795513931799317608292977574376954729552861360597103229877031117089231816770880909815561950691603994439997197261395452797893557057320175747162837857668062550646101714062365530246698404923128445182100334335447738834779014705114350
c3 = 3204718091370324153305164801961074660508922478706979436653573192321723216725523523538914956544950802616295043619768261075799875855502834749045520466140056621489305006966280527055668378303630674311102581232313032585389907028715671091914904062961720585667564982641321454541632782484415075257140508738041786400512095949826279576159569786734978545737717138115729502475357594151593143140355121154223614868465202149338507796306863351134218879326031985027900678671697876083351974546516576983143592764763925335805465720148057651958521255276602933604064541840892578409973858867533575728482926007556060584654853884046046420855

n = [n1, n2, n3]
c = [c1, c2, c3]
m = rsa_gb_def(c, n, e)
print(libnum.n2s(m))

私钥d相关攻击

维纳攻击small d

低解密指数攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from secret import flag
from Crypto.Util.number import *

p = getPrime(1024)
q = getPrime(1024)

d = getPrime(32)
e = inverse(d, (p-1)*(q-1))
n = p*q
m = bytes_to_long(flag)

c = pow(m,e,n)

print(c)
print(e)
print(n)

# c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
# e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
# n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433

解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import gmpy2
def transform(x,y): #使用辗转相处将分数 x/y 转为连分数的形式
res=[]
while y:
res.append(x//y)
x,y=y,x%y
return res

def continued_fraction(sub_res):
numerator,denominator=1,0
for i in sub_res[::-1]: #从sublist的后面往前循环
denominator,numerator=numerator,i*numerator+denominator
return denominator,numerator #得到渐进分数的分母和分子,并返回


#求解每个渐进分数
def sub_fraction(x,y):
res=transform(x,y)
res=list(map(continued_fraction,(res[0:i] for i in range(1,len(res))))) #将连分数的结果逐一截取以求渐进分数
return res

def get_pq(a,b,c): #由p+q和pq的值通过维达定理来求解p和q
par=gmpy2.isqrt(b*b-4*a*c) #由上述可得,开根号一定是整数,因为有解
x1,x2=(-b+par)//(2*a),(-b-par)//(2*a)
return x1,x2

def wienerAttack(e,n):
for (d,k) in sub_fraction(e,n): #用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数
if k==0: #可能会出现连分数的第一个为0的情况,排除
continue
if (e*d-1)%k!=0: #ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n)
continue

phi=(e*d-1)//k #这个结果就是 φ(n)
px,qy=get_pq(1,n-phi+1,n)
if px*qy==n:
p,q=abs(int(px)),abs(int(qy)) #可能会得到两个负数,负负得正未尝不会出现
d=gmpy2.invert(e,(p-1)*(q-1)) #求ed=1 (mod φ(n))的结果,也就是e关于 φ(n)的乘法逆元d
return d
print("该方法不适用")


e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473
n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159
d=wienerAttack(e,n)
print("d=",d)

d低位泄露

Coppersmith 攻击 (ruanx.net)

1
2
3
4
5
6
7
8
9
10
11
n=92896523979616431783569762645945918751162321185159790302085768095763248357146198882641160678623069857011832929179987623492267852304178894461486295864091871341339490870689110279720283415976342208476126414933914026436666789270209690168581379143120688241413470569887426810705898518783625903350928784794371176183

e=3

m=random.getrandbits(512)

c=pow(m,e,n)=56164378185049402404287763972280630295410174183649054805947329504892979921131852321281317326306506444145699012788547718091371389698969718830761120076359634262880912417797038049510647237337251037070369278596191506725812511682495575589039521646062521091457438869068866365907962691742604895495670783101319608530

d&((1<<512)-1)=787673996295376297668171075170955852109814939442242049800811601753001897317556022653997651874897208487913321031340711138331360350633965420642045383644955

long_to_bytes(m).encode('hex')=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def getFullP(low_p, n):
R.<x> = PolynomialRing(Zmod(n), implementation='NTL')
p = x*2^512 + low_p
root = (p-n).monic().small_roots(X = 2^128, beta = 0.4)
if root:
return p(root[0])
return None

def phase4(low_d, n, c):
maybe_p = []
for k in range(1, 4):
p = var('p')
p0 = solve_mod([3*p*low_d == p + k*(n*p - p^2 - n + p)], 2^512)
maybe_p += [int(x[0]) for x in p0]
print(maybe_p)

for x in maybe_p:
P = getFullP(x, n)
if P: break

P = int(P)
Q = n // P

assert P*Q == n

d = inverse_mod(3, (P-1)*(Q-1))
print(hex(power_mod(c, d, n))[2:])



n = 92896523979616431783569762645945918751162321185159790302085768095763248357146198882641160678623069857011832929179987623492267852304178894461486295864091871341339490870689110279720283415976342208476126414933914026436666789270209690168581379143120688241413470569887426810705898518783625903350928784794371176183
c = 56164378185049402404287763972280630295410174183649054805947329504892979921131852321281317326306506444145699012788547718091371389698969718830761120076359634262880912417797038049510647237337251037070369278596191506725812511682495575589039521646062521091457438869068866365907962691742604895495670783101319608530
low_d = 787673996295376297668171075170955852109814939442242049800811601753001897317556022653997651874897208487913321031340711138331360350633965420642045383644955

phase4(low_d, n, c)

公约数

题目如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import *
m=bytes_to_long(b'xxxxxx')
e=65537
p=getPrime(1024)
q1=getPrime(1024)
q2=getPrime(1024)
n1=p*q1
n2=p*q2
c1=pow(m,e,n1)
c2=pow(m,e,n2)
n3=n1^n2
print('n1=',n1)
print('n3=',n3)
print('c1=',c1)
print('c2=',c2)
#n1= 9852079772293301283705208653824307027320071498525390578148444258198605733768947108049676831872672654449631852459503049139275329796717506126689710613873813880735666507857022786447784753088176997374711523987152412069255685005264853118880922539048290400078105858759506186417678959028622484823376958194324034590514104266608644398160457382895380141070373685334979803658172378382884352616985632157233900719194944197689860219335238499593658894630966428723660931647038577670614850305719449893199713589368780231046895222526070730152875112477675102652862254926169713030701937231206405968412044029177246460558028793385980934233
#n3= 4940268030889181135441311597961813780480775970170156650560367030148383674257975796516865571557828263935532335958510269356443566533284856608454193676600884849913964971291145182724888816164723930966472329604608512023988191536173112847915884014445539739070437180314205284883149421228744714989392788108329929896637182055266508625177260492776962915873036873839946591259443753924970795669864031580632650140641456386202636466624658715315856453572441182758855085077441336516178544978457053552156714181607801760605521338788424464551796638531143900048375037218585999440622490119344971822707261432953755569507740550277088437182
#c1= 7066425618980522033304943700150361912772559890076173881522840300333719222157667104461410726444725540513601550570478331917063911791020088865705346188662290524599499769112250751103647749860198318955619903728724860941709527724500004142950768744200491448875522031555564384426372047270359602780292587644737898593450148108629904854675417943165292922990980758572264063039172969633878015560735737699147707712154627358077477591293746136250207139049702201052305840453700782016480965369600667516646007546442708862429431724013679189842300429421340122052682391471347471758814138218632022564279296594279507382548264409296929401260
#c2= 854668035897095127498890630660344701894030345838998465420605524714323454298819946231147930930739944351187708040037822108105697983018529921300277486094149269105712677374751164879455815185393395371001495146490416978221501351569800028842842393448555836910486037183218754013655794027528039329299851644787006463456162952383099752894635657833907958930587328480492546831654755627949756658554724024525108575961076341962292900510328611128404001877137799465932130220386963518903892403159969133882215092783063943679288192557384595152566356483424061922742307738886179947575613661171671781544283180451958232826666741028590085269
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import *
import gmpy2
import binascii
n1= 9852079772293301283705208653824307027320071498525390578148444258198605733768947108049676831872672654449631852459503049139275329796717506126689710613873813880735666507857022786447784753088176997374711523987152412069255685005264853118880922539048290400078105858759506186417678959028622484823376958194324034590514104266608644398160457382895380141070373685334979803658172378382884352616985632157233900719194944197689860219335238499593658894630966428723660931647038577670614850305719449893199713589368780231046895222526070730152875112477675102652862254926169713030701937231206405968412044029177246460558028793385980934233
n3= 4940268030889181135441311597961813780480775970170156650560367030148383674257975796516865571557828263935532335958510269356443566533284856608454193676600884849913964971291145182724888816164723930966472329604608512023988191536173112847915884014445539739070437180314205284883149421228744714989392788108329929896637182055266508625177260492776962915873036873839946591259443753924970795669864031580632650140641456386202636466624658715315856453572441182758855085077441336516178544978457053552156714181607801760605521338788424464551796638531143900048375037218585999440622490119344971822707261432953755569507740550277088437182
c1= 7066425618980522033304943700150361912772559890076173881522840300333719222157667104461410726444725540513601550570478331917063911791020088865705346188662290524599499769112250751103647749860198318955619903728724860941709527724500004142950768744200491448875522031555564384426372047270359602780292587644737898593450148108629904854675417943165292922990980758572264063039172969633878015560735737699147707712154627358077477591293746136250207139049702201052305840453700782016480965369600667516646007546442708862429431724013679189842300429421340122052682391471347471758814138218632022564279296594279507382548264409296929401260
c2= 854668035897095127498890630660344701894030345838998465420605524714323454298819946231147930930739944351187708040037822108105697983018529921300277486094149269105712677374751164879455815185393395371001495146490416978221501351569800028842842393448555836910486037183218754013655794027528039329299851644787006463456162952383099752894635657833907958930587328480492546831654755627949756658554724024525108575961076341962292900510328611128404001877137799465932130220386963518903892403159969133882215092783063943679288192557384595152566356483424061922742307738886179947575613661171671781544283180451958232826666741028590085269
e=65537

n2=n1^n3
p=gmpy2.gcd(n1,n2)
q1=n1//p
q2=n2//p
phi1=(p-1)*(q1-1)
d=gmpy2.invert(e,phi1)
m=gmpy2.powmod(c1,d,n1)
print(binascii.unhexlify(hex(m)[2:]))

公钥加签

flag.enc和pub.pem两个文件

1
openssl rsa -pubin -text -modulus -in warmup -in pub.pem

生成n,e ;

16进制转10进制

1
2
s=''
int(s,16)

yafu分解factor()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#coding=utf-8
import math
import sys
from Crypto.PublicKey import RSA
arsa=RSA.generate(1024)
arsa.p=
arsa.q=
arsa.e=
arsa.n=arsa.p*arsa.q
Fn=long((arsa.p-1)*(arsa.q-1))
i=1
while(True):
x=(Fn*i)+1
if(x%arsa.e==0):
arsa.d=x/arsa.e
break
i=i+1
private=open('private.pem','w')
private.write(arsa.exportKey())
private.close()

生成私钥

在kali终端输入openssl进入openssl

1
rsautl -decrypt -in flag.enc(密文名称) -inkey private.pem(我们所求得密钥名称)