黑龙江省赛复现
Easy_RSA
import libnum
import gmpy2
from Crypto.Util.number import *
import flag,e1,e2
#生成素数
p=libnum.generate_prime(1024)
q=libnum.generate_prime(1024)
ec1=pow(bytes_to_long(str(e1).ljust(20,"D").encode()),3,p*q)
ec2=pow(bytes_to_long(str(e2).ljust(20,"A").encode()),5,p*q)
m=libnum.s2n(flag)
n=p*q
c1=pow(m,e1,n)
c2=pow(m,e2,n)
print("n1=",n)
print("ec1=",ec1)
print("c1=",c1)
print("n2=",n)
print("ec2=",ec2)
print("c2=",c2)
# n1= 27929259512873502442719286790227037320417984116570178470037376373267390909685621247157535458203218619293705428397911754453556082799420494496904478215709219317542924547049229150153308059698341011305505985823374280465467094476511869541135508518055946815227085548571701115773386101962695795789178321155174729047033298389886321980592410739667139376075568555729949442873964097042006391886635957242436522435588904492484342259494858627609438654632887244523845583473711604632109405043439047289868784236481926074763997559971182741918345193506253460323445846136663027639802131457594564405906763806426256107923417802076262573737
# ec1= 24979839185643431898760549059477070141596292955202172081572583839065034831779499992829742773873064296311713734486020739853343887094398935731264
# c1= 17695186679431856780362905635257355413310120106982055323913669124182832151093921194946365178919380690844190324897933591567360925332869903671651849060145290581360223200011298757871213149464298017718829480721410479504940393501845624196721013966839230696831321482946841011452400364600924503121451272593970649100410603943321149604376033957124800064565646929720179239631538966228020882733213221035707244692798307971636126058586394357032072695921642665492919186476321028415907982915011972040971875733852055633796811898421692604356476773910338982400925245494707729878821466569634334862311750349321720627252469986162120031838
# n2= 27929259512873502442719286790227037320417984116570178470037376373267390909685621247157535458203218619293705428397911754453556082799420494496904478215709219317542924547049229150153308059698341011305505985823374280465467094476511869541135508518055946815227085548571701115773386101962695795789178321155174729047033298389886321980592410739667139376075568555729949442873964097042006391886635957242436522435588904492484342259494858627609438654632887244523845583473711604632109405043439047289868784236481926074763997559971182741918345193506253460323445846136663027639802131457594564405906763806426256107923417802076262573737
# ec2= 2838620519239658396968146844964839207179863729944843241951228382052657801460586137213053314019699976475855578055607417923815486109050614096157077528657405905877896929808094661904905136761365045387901486261011216958309860644255996588189249
# c2= 10770781309274554738409447671578241895686779262243081931452089039730277591151694112684863740412412713684216227740930573490322958500198235497947657939304932868457999239593145330718657422535271157683896034543125292529800047408131765376686654378173684648427311300423776510153307756388404568013401217965931456538849277670384454454507752525534110389604969437991055504757081225690155489265359117617764571537216746554060783131168749700810806387918510612057149583061938836035963175555630655718716139689761210220525955656039741684390906935720406757364893793459339618913268943282961044530062475057887777134887741597041684698119
此题的ec1,ec2都经过了填充,但很明显,此处的填充完后只有208=160bits,就算是经过了指数运算后仍然远小于pq。。。
所以我们大可以试试直接将ec1,ec2直接开方
确实可以开出来(
得到ec1为34967,ec2为65535
之后就是一个简单的共模攻击了
exp:
from Crypto.Util.number import *
import gmpy2
ec1 = 24979839185643431898760549059477070141596292955202172081572583839065034831779499992829742773873064296311713734486020739853343887094398935731264
ec1 = gmpy2.iroot(ec1, 3)[0]
print(long_to_bytes(ec1))
ec2= 2838620519239658396968146844964839207179863729944843241951228382052657801460586137213053314019699976475855578055607417923815486109050614096157077528657405905877896929808094661904905136761365045387901486261011216958309860644255996588189249
ec2 = gmpy2.iroot(ec2, 5)[0]
print(long_to_bytes(ec2))
e1 = 34967
e2 = 65535
n = 27929259512873502442719286790227037320417984116570178470037376373267390909685621247157535458203218619293705428397911754453556082799420494496904478215709219317542924547049229150153308059698341011305505985823374280465467094476511869541135508518055946815227085548571701115773386101962695795789178321155174729047033298389886321980592410739667139376075568555729949442873964097042006391886635957242436522435588904492484342259494858627609438654632887244523845583473711604632109405043439047289868784236481926074763997559971182741918345193506253460323445846136663027639802131457594564405906763806426256107923417802076262573737
c1 = 17695186679431856780362905635257355413310120106982055323913669124182832151093921194946365178919380690844190324897933591567360925332869903671651849060145290581360223200011298757871213149464298017718829480721410479504940393501845624196721013966839230696831321482946841011452400364600924503121451272593970649100410603943321149604376033957124800064565646929720179239631538966228020882733213221035707244692798307971636126058586394357032072695921642665492919186476321028415907982915011972040971875733852055633796811898421692604356476773910338982400925245494707729878821466569634334862311750349321720627252469986162120031838
c2 = 10770781309274554738409447671578241895686779262243081931452089039730277591151694112684863740412412713684216227740930573490322958500198235497947657939304932868457999239593145330718657422535271157683896034543125292529800047408131765376686654378173684648427311300423776510153307756388404568013401217965931456538849277670384454454507752525534110389604969437991055504757081225690155489265359117617764571537216746554060783131168749700810806387918510612057149583061938836035963175555630655718716139689761210220525955656039741684390906935720406757364893793459339618913268943282961044530062475057887777134887741597041684698119
_, s1, s2 = gmpy2.gcdext(e1, e2)
m = pow(c1, s1, n)*pow(c2, s2, n) % n
print(long_to_bytes(m))
Easy_Crypto
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
from secret import FLAG
m = bytes_to_long(FLAG)
def getpq(nbit):
p = getPrime(nbit)
q = getPrime(nbit)
if p > q:
return p, q
else:
return q, p
p, q = getpq(512)
P = (p - q) & ((1 << 130) - 1)
n = p * q
leak_p = p >> 256
c = pow((1 + P * n), m, n ** 3)
print('n =', n)
print('leak_p =', leak_p)
print("c =", c)
# n = 135133139540786818977969958456509467902948924003478556140490841984247464940261764739984274397650928404945721248284577232814352745333641188749824519153271662051302477973525156608141358709265683759057060630360909926255299541198485901065352661702656282587105799982740927802530997159098015074633017964344230291287
# leak_p = 115314121469787984258489158421056136177545051135641551928888818017665807264468
# c = 1836794759996264077871820946090708779709415760553736759453665641907562256633157424959089180650539327925671892742819931875681606982615287882656254828326465758462357812873839261469783652663796071814218493268788421243190729887313099383264588659922912876424206670310928514588754069909128149471326084547056385690037197908766053620702238356084124023146075698878494434053246157524775269473152458661801907641122308756667762880284617915774590075511686821816948174618196839335059944389423693187930672934293905608970421003536691336581450927887931599275461176935079227494931457562345640133982771901848553204154760760399724074615092290799119053032875792219794072963200108352944441876206386518960615891547166767499506114294860833404421893612197040731184031783165365621722947731966143226777081983415797778111715332055871302609049501876860012070502369090417942239749695034267695710324328867728296996779
p的高位已经给出,很自然联想到可以p高位泄露攻击,但只给了刚好256位,可能不太够,得爆破几位
n = 135133139540786818977969958456509467902948924003478556140490841984247464940261764739984274397650928404945721248284577232814352745333641188749824519153271662051302477973525156608141358709265683759057060630360909926255299541198485901065352661702656282587105799982740927802530997159098015074633017964344230291287
pbits = 512
for i in range(0,256):
p4 = 0xfef17ad62b2573f0f1fd707b2f273922860034731234b9ba82fc303b7c4faad400
p4 = p4 + i
kbits = pbits - 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",n)
print ("p",p)
print ("q",n/p)
得到p,q
回过头看m加密
可以发现$c \equiv (1+P*n)^{m}\ (mod\ n^{3})$
通过二次项展开可以得到$c \equiv (1+P*n*m)+C_{m}^{2}{P}^{2}{n}^{2}\ (mod\ n^{3})$
转移到$mod\ n^{2}$下得到
$c \equiv (1+P*n*m)\ (mod\ n^{2})$
这样我们便可以通过c,P,n得到m
exp:
from Crypto.Util.number import *
q = 10120465347855011176216116854406657716210971137988515839650722657457130494685812171761795141588424375299868315964294503826721743852498238577704636503052409
p = 13352463043552409670211183534740157814546713901105410408023687926498813469217507846107364405269402732967687839808637375591530105677153038557366731161035343
c = 1836794759996264077871820946090708779709415760553736759453665641907562256633157424959089180650539327925671892742819931875681606982615287882656254828326465758462357812873839261469783652663796071814218493268788421243190729887313099383264588659922912876424206670310928514588754069909128149471326084547056385690037197908766053620702238356084124023146075698878494434053246157524775269473152458661801907641122308756667762880284617915774590075511686821816948174618196839335059944389423693187930672934293905608970421003536691336581450927887931599275461176935079227494931457562345640133982771901848553204154760760399724074615092290799119053032875792219794072963200108352944441876206386518960615891547166767499506114294860833404421893612197040731184031783165365621722947731966143226777081983415797778111715332055871302609049501876860012070502369090417942239749695034267695710324328867728296996779
n = 135133139540786818977969958456509467902948924003478556140490841984247464940261764739984274397650928404945721248284577232814352745333641188749824519153271662051302477973525156608141358709265683759057060630360909926255299541198485901065352661702656282587105799982740927802530997159098015074633017964344230291287
s = n * n
P = (p - q) & ((1 << 130) - 1)
g = P * n
c = c % s - 1
c = c // g
print(long_to_bytes(c))