1.共模攻击:
import gmpy2
from Crypto.Util.number import *
def Commodulus(e1, e2, n, c1, c2):
g, s, t = gmpy2.gcdext(e1, e2) #g=e1*s+t*e2
m = gmpy2.powmod(c1, s, n) * gmpy2.powmod(c2, t, n) % n #幂取模,结果是 x = (c^t) mod n
print(long_to_bytes(m))
n = 16083214012638388663784521954622543045708903686589880528711880230698602817697997380543200768660883701383088153716426277227007488632840757171121370309401375874563915993808574166897288857497860302677982653939994860362835482720701397641826151564818523685533076796342606201005914811273943686796396237073344829728184519773946965610605096544342524362362461602653060886529901512437308424885213454571496693957407506264908554886708080545957821146720531872251855895768339549873719942212035943303966017435806880270694222061139516388747219293476787639922972482077360726936780982113094370207160279202403541678219198642190754621383
e1 = 2333
e2 = 23333
c1 = 4944405402225804339898252584518133767856406646249564382227685038047513515431245453943040701069968915476361792382122280755353274617424667793336796623723914559575269601832955753855993184244386734062811836260918753012696477615577988449692691314668133500013048312665481402135382287614750525215272490220938713668665692329719115647760562353429578730365840277086852860597005486082956680256590327407559949649584759812170174311526394806043211343044265907044168640909953661809811847927388079078303020542880557247053604834432185767108642131078127156691025192078511566714696010552401059130895526376490822816868319766073162568049
c2 = 11863581449110679506024274134666181367837473368100054843316578483117405767899134169014721870302871234881206143904730705290442330442439596377140286127278773898090404689672402351240966190856406939435251619065783216442053701246713535711655991342135264010287996212379191016108670983776732911762966210503499355546289551877817318255927731876830493191794531458129659943130330960702384582747657461399459306963037530735867297905149683168674083995472852266279410443295140541962184944033145678873265842380004922976892553624101873405742602120680775552886212919350450731408676621073336654797824300438267183415076998086836456080800
Commodulus(e1, e2, n, c1, c2)
2.维纳攻击:适用于e过大,n无法分解情况
from Crypto.Util.number import *
'''
Created on Dec 14, 2011
@author: pablocelayes
'''
def egcd(a, b):
'''
Extended Euclidean Algorithm
returns x, y, gcd(a,b) such that ax + by = gcd(a,b)
'''
u, u1 = 1, 0
v, v1 = 0, 1
while b:
q = a // b
u, u1 = u1, u - q * u1
v, v1 = v1, v - q * v1
a, b = b, a - q * b
return u, v, a
def gcd(a, b):
'''
2.8 times faster than egcd(a,b)[2]
'''
a, b = (b, a) if a < b else (a, b)
while b:
a, b = b, a % b
return a
def modInverse(e, n):
'''
d such that de = 1 (mod n)
e must be coprime to n
this is assumed to be true
'''
return egcd(e, n)[0] % n
def totient(p, q):
'''
Calculates the totient of pq
'''
return (p - 1) * (q - 1)
def bitlength(x):
'''
Calculates the bitlength of x
'''
assert x >= 0
n = 0
while x > 0:
n = n + 1
x = x >> 1
return n
def isqrt(n):
'''
Calculates the integer square root
for arbitrary large nonnegative integers
'''
if n < 0:
raise ValueError('square root not defined for negative numbers')
if n == 0:
return 0
a, b = divmod(bitlength(n), 2)
x = 2 ** (a + b)
while True:
y = (x + n // x) // 2
if y >= x:
return x
x = y
def is_perfect_square(n):
'''
If n is a perfect square it returns sqrt(n),
otherwise returns -1
'''
h = n & 0xF # last hexadecimal "digit"
if h > 9:
return -1 # return immediately in 6 cases out of 16.
# Take advantage of Boolean short-circuit evaluation
if (h != 2 and h != 3 and h != 5 and h != 6 and h != 7 and h != 8):
# take square root if you must
t = isqrt(n)
if t * t == n:
return t
else:
return -1
return -1
def rational_to_contfrac(x, y):
'''
Converts a rational x/y fraction into
a list of partial quotients [a0, ..., an]
'''
a = x // y
pquotients = [a]
while a * y != x:
x, y = y, x - a * y
a = x // y
pquotients.append(a)
return pquotients
# TODO: efficient method that calculates convergents on-the-go, without doing partial quotients first
def convergents_from_contfrac(frac):
'''
computes the list of convergents
using the list of partial quotients
'''
convs = []
for i in range(len(frac)):
convs.append(contfrac_to_rational(frac[0:i]))
return convs
def contfrac_to_rational(frac):
'''Converts a finite continued fraction [a0, ..., an]
to an x/y rational.
'''
if len(frac) == 0:
return (0, 1)
num = frac[-1]
denom = 1
for _ in range(-2, -len(frac) - 1, -1):
num, denom = frac[_] * num + denom, num
return (num, denom)
def hack_RSA(e, n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = rational_to_contfrac(e, n)
convergents = convergents_from_contfrac(frac)
for (k, d) in convergents:
# check if d is actually the key
if k != 0 and (e * d - 1) % k == 0:
phi = (e * d - 1) // k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s * s - 4 * n
if (discr >= 0):
t = is_perfect_square(discr)
if t != -1 and (s + t) % 2 == 0:
print("Hacked!")
return d
if __name__ == "__main__":
N = 460657813884289609896372056585544172485318117026246263899744329237492701820627219556007788200590119136173895989001382151536006853823326382892363143604314518686388786002989248800814861248595075326277099645338694977097459168530898776007293695728101976069423971696524237755227187061418202849911479124793990722597
e = 354611102441307572056572181827925899198345350228753730931089393275463916544456626894245415096107834465778409532373187125318554614722599301791528916212839368121066035541008808261534500586023652767712271625785204280964688004680328300124849680477105302519377370092578107827116821391826210972320377614967547827619
c = 38230991316229399651823567590692301060044620412191737764632384680546256228451518238842965221394711848337832459443844446889468362154188214840736744657885858943810177675871991111466653158257191139605699916347308294995664530280816850482740530602254559123759121106338359220242637775919026933563326069449424391192
d = hack_RSA(e, N)
m = pow(c, d, N)
# import hashlib
# flag = "flag{" + hashlib.md5(hex(d)[:-1].encode()).hexdigest() + "}"
# # print(flag)
print (d)
print(long_to_bytes(m))
3.低指数广播攻击:利用中国剩余定理(py2的脚本)
# -*- coding: UTF-8 -*-
import gmpy2
import libnum
def CRT(data):
sum = 0
m = 1
for n in data:
m = m*n[0]
for n,c in data:
m1 = m/n
mr = gmpy2.invert(m1,n)
sum = sum+mr*m1*c
return sum%m
#观察发现数字最大为4,所以需要先将5进制数字转化为10进制
N1 = int('331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101331214303223312402430402404413033243132101010422240133122211400434023222214231402403403200012221023341333340042343122302113410210110221233241303024431330001303404020104442443120130000334110042432010203401440404010003442001223042211442001413004',5)
c1 = int('310020004234033304244200421414413320341301002123030311202340222410301423440312412440240244110200112141140201224032402232131204213012303204422003300004011434102141321223311243242010014140422411342304322201241112402132203101131221223004022003120002110230023341143201404311340311134230140231412201333333142402423134333211302102413111111424430032440123340034044314223400401224111323000242234420441240411021023100222003123214343030122032301042243',5)
N2 = int('302240000040421410144422133334143140011011044322223144412002220243001141141114123223331331304421113021231204322233120121444434210041232214144413244434424302311222143224402302432102242132244032010020113224011121043232143221203424243134044314022212024343100042342002432331144300214212414033414120004344211330224020301223033334324244031204240122301242232011303211220044222411134403012132420311110302442344021122101224411230002203344140143044114',5)
c2 = int('112200203404013430330214124004404423210041321043000303233141423344144222343401042200334033203124030011440014210112103234440312134032123400444344144233020130110134042102220302002413321102022414130443041144240310121020100310104334204234412411424420321211112232031121330310333414423433343322024400121200333330432223421433344122023012440013041401423202210124024431040013414313121123433424113113414422043330422002314144111134142044333404112240344',5)
N3 = int('332200324410041111434222123043121331442103233332422341041340412034230003314420311333101344231212130200312041044324431141033004333110021013020140020011222012300020041342040004002220210223122111314112124333211132230332124022423141214031303144444134403024420111423244424030030003340213032121303213343020401304243330001314023030121034113334404440421242240113103203013341231330004332040302440011324004130324034323430143102401440130242321424020323',5)
c3 = int('10013444120141130322433204124002242224332334011124210012440241402342100410331131441303242011002101323040403311120421304422222200324402244243322422444414043342130111111330022213203030324422101133032212042042243101434342203204121042113212104212423330331134311311114143200011240002111312122234340003403312040401043021433112031334324322123304112340014030132021432101130211241134422413442312013042141212003102211300321404043012124332013240431242',5)
e = 3
n = [N1,N2,N3]
c = [c1,c2,c3]
data = zip(n,c)
m_e = CRT(data)
m = gmpy2.iroot(m_e,e)[0]
print libnum.n2s(m)
4.已知dp,dq:
#coding:utf-8
from Crypto.Util.number import *
def RSA_dpdq(p,q,c,dp,dq):
m1 = pow(c,dp,p)
m2 = pow(c,dq,q)
qinv = inverse(q,p)
h = (qinv*(m1 - m2)) % p
m = m2 + h * q
print (long_to_bytes(m))
p= 179361074413263697829999005814546179096338251344605155492350917550408915635839919536158715514795196578473034682853650147697648138514548794413428404094860743787113850190924056019307495205914830488435938921721750461015019866101069038340890406381470474569514245532335549692911319669909660529671092887579254089841
q= 173835595299488471664720455055270783584907101280431946406552831195941371196026061249385544447021385360873734720942054760579124666786102164766159947255113097404541948119682544948561794690528398106216930762814472842260707467541709548511410564591303589518935143237786002751598606698519725781106792846894755964463
dq= 85420472573122461227866053292032597075977665893083760350284989789494421746445874490367457670810026308216393074953353548525109949634246824147114072072320402044888672005832685010352686821395189474840319793180604596062740486819860754997352118987722062298667735063088948725338076660804267040828282601300009476777
dp= 40173355681711061239399963476383163143798910409195707424389568010779444781093034146684678655441638930305105148383489181959103667016419148773894373311388389124479976302738517452849760015374884366689826318445360254775767530013543378760180207749417963840363452861271549413953114445803193721333627912427725876753
c= 9766441985129844560019248100335265224864673427740570851739663484929172951774608983863007909781231149939524112862707457126539070597704329598419487190548565088644236637208267519648456264153799758486217082215926007234828186809396123615231707592709578628053901648532553911011386785261328710958617957713754641724108641983981428692803380139764569751627517242442987987996276078388547228292107648936726531469395113308901910257869544546190203266474033877973975761458955817124112794966846072260497147758360059384239579835093759557643039752186121549033766866833574085918197046373876734103651933335070704951351790263619835894130
print (RSA_dpdq(p,q,c,dp,dq))
5.还有一类题型,n进行分解的时候,可以分解成3个素数p,q,r,此时只需要计算phi(n)时,让phi(n)=(p-1)*(q-1)*(r-1)即可
6.n分解出来的p相同,则n时p的r次方,原理:
欧拉函数φ(n)的定义是小于n的自然数中与n互质的数的个数。
p^r 质因数就只有p,那么不与它互质的数都含有p,
和它不互质的数的个数:p^r/p=p^r-1/p=p^{r-1}
剩下就是互质的数,其个数就是:p^r-p^{r-1}
则有 φ(n)=p^r-p^{r-1}
首先进行分解发现p相同,有4个:
所以脚本为:
import libnum
import gmpy2
n= 8728589998777982696703940018364436561769679950282731827002399945820519626630239261319979808404426258563397495169681599073815794013914620870334635363415860236091892304738823310165557915602091780358896749588269684770012690738058843365220895883269596248137195018693952271988305757700968804667123708093004971368530057417274917306936884549277317220129475657174220318156910434608983375960022033492495856119260793686742733850272256173907450229747656796655716934718664918221274680117850849415470788295824869164880840382356808898064880080213936002040667302618190824116124200896763471960023079024139735441967770305579426290561
e= 65537
c= 1465588858007680887950755019340127657311002100000046397447311397428442921759230618584011648408572671005139182825463405538111012102590465761751745664370670840392175162154595485471520075855504299902170889163643118381246916627503015519764730758098584564744019290491548278499257338223884379516365562400137688156919398735700425005486588919949594095827647523977040403331416767981921771152227523364146160326575910559036981829702510036555588506777191403921818438886116726068926492791242805894408776798336721989949917577680258986296019916893622187881181000328457760294312967378439822673204825874847498815102583233675832797900
#分解n
#yafu-x64.exe factor()
p= 9665760358496789369385498497685947307023279674165117573518923758539132148704165168622034787978336928985555102380665909335419628100028226879863551889800991
phi_n=p**4-p**3
#求逆元
d=libnum.invmod(e,phi_n)
m=pow(c,d,n)
print(m)
#数字转字节,转字符串
print(libnum.n2s(int(m)).decode())