Crypto專項

sbhg發表於2024-03-31

RSA

一、SameMod

  1. 根據題目共模,我去計算了題目所給出的兩個message和哪個數的取餘與題目所給的例子一致,發現得到的資料沒有一點線索。

Crypto專項

  1. 不像是ascii碼,看來之前想的思路完全錯誤。檢視了大佬的wp,才知道這個是RSA的共模攻擊。

共模是指:就是明文m相同。用兩個公鑰e1,e2加密得到兩個私鑰d1,d2 和兩個密文c1,c2
共模攻擊,即當m不變的情況下,知道n,e1,e2,c1,c2, 可以在不知道d1,d2的情況下,解出m,利用條件為=> gcd(e1,e2)=1。

故編寫指令碼得出答案。

from gmpy2 import invert


def gongmogongji(n, c1, c2, e1, e2):
def egcd(a, b):
if b == 0:
return a, 0
else:
x, y = egcd(b, a % b)
return y, x - (a // b) * y

s = egcd(e1, e2)
s1 = s[0]
s2 = s[1]
if s1 < 0:
s1 = - s1
c1 = invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = invert(c2, n)
m = pow(c1, s1, n) * pow(c2, s2, n) % n
return m


n = 6266565720726907265997241358331585417095726146341989755538017122981360742813498401533594757088796536341941659691259323065631249
e1 = 773
e2 = 839
c1 = 3453520592723443935451151545245025864232388871721682326408915024349804062041976702364728660682912396903968193981131553111537349
c2 = 5672818026816293344070119332536629619457163570036305296869053532293105379690793386019065754465292867769521736414170803238309535

result = gongmogongji(n, c1, c2, e1, e2)
print(result)
print(result)
result = str(result)
flag = ""
i = 0
while i < len(result):
if result[i] == '1': # 1開頭的兩位數不是可見字元,故取3位
c = chr(int(result[i:i + 3]))
i += 3
else:
c = chr(int(result[i:i + 2]))
i += 2
flag += c
print(flag)

1663914637540

總結:

共模攻擊一般的出題指令碼:(出處:https://www.bilibili.com/read/cv13392581/)

coding:utf-8

import libnum

import gmpy2

#生成素數

p=libnum.generate_prime(1024)

q=libnum.generate_prime(1024)

e1=2333

e2=23333

m="flag{6ed4c74e022cb18c8039e96de93aa9ce}"

m=libnum.s2n(m)

n=p*q

c1=pow(m,e1,n)

c2=pow(m,e2,n)

print("n1=",n)

print("e1=",e1)

print("c1=",c1)

print("n2=",n)

print("e2=",e2)

print("c2=",c2)

解題指令碼:

#coding:utf-8

import gmpy2

import libnum

n= 25333966058003377512707481338795714713737652659944601834182685873529702913988641983855700459996104700470621411559153944988952210084014634675583566338568882440708528997808798650962116756969822211586531522430245040013570571043385238601846104615050089457836721437790715225367971106085839523500735480715155424498941150468093083816830215632716244390679417218873179734276657411907216486790815037105108306055794473002315541787461904728375164737225486501009857299717749346279371251245318729951905832578739696926931502225899707226264570557623527701806829827566904224572897378639191756878049342203546309520458672464170859577433

e1= 2333

c1= 11355981897781478907853356911752561659125575027336719997290835661089901154031171698660586203170528368228850895159361637188990782030255983633790580700032092629587631108597144196551438410868034739981960656110887650747325311613900008001234835897835613759692146419080113176963747835592656185435741504176116672174539018089139547795447109458469225330809064539216773123671814859510069089532677704482026169178543062578686794346026774853085101278125763460212801929360456888869350105294595904940799522522144740464043605342348269086324747729288399275079874271519208155039364092577755518532799345651172433227745483422620900776136

e2= 23333

c2= 1326499538902841116411674554069945581390130048432351353260154261863309471312810811160302458644816390944833633923435634961251092531893503039914793217247984595331920909367627316087404934402312358642315675486438968585084964845763881078835787872160374025547400141298650794551970291119975344578667689961134814676553190178139842507675899262024572370313939107080072875068218336255452161407859907308656094331557912187788276334833723893856310434523337557011032081467262457427167978528280339494077785813461280853735266463152709443731638714219391773144349752633555310299318290576258086971373777118482642702020599928071855133041

#共模攻擊

#共模攻擊函式

def rsa_gong_N_def(e1,e2,c1,c2,n):

e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)

s = gmpy2.gcdext(e1, e2)

s1 = s[1]

s2 = s[2]

if s1 < 0:

s1 = - s1

c1 = gmpy2.invert(c1, n)

elif s2 < 0:

s2 = - s2

c2 = gmpy2.invert(c2, n)

m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n

return int(m)

m = rsa_gong_N_def(e1,e2,c1,c2,n)

print(m)

print(libnum.n2s(int(m)))

二、[GWCTF2019]BabyRSA

  1. 題目給出n和兩個明文,及其的生成過程。

Crypto專項

Crypto專項

  1. 用yahu工具對n進行素數分解得到p和q。

Crypto專項

  1. 利用c1和c2的等式求解出F1和F2,再還原出flag1和flag2進行拼接。

from gmpy2 import *
from Crypto.Util.number import *
import sympy

N = 636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1 = 90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2 = 487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
p = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377748737
q = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377747699
phi_n = (p - 1) * (q - 1)
e = 0x10001
d = inverse(e, phi_n)
c1 = pow(m1, d, N)
c2 = pow(m2, d, N)
# print(c1)
# print(c2 < N)
F1 = sympy.Symbol("F1")
F2 = sympy.Symbol("F2")
f1 = F1 + F2 - c1
f2 = pow(F1, 3) + pow(F2, 3) - c2

result = sympy.solve([f1, f2], [F1, F2])
flag1 = long_to_bytes(result[0][1])
flag2 = long_to_bytes(result[0][0])
flag = flag1 + flag2
print(flag)

1666091969(1)

三、[BJDCTF2020]easyrsa

  1. 題目給出了c,z,n。

Crypto專項

  1. 題目中Fraction函式的第一個引數為分子,第二個引數為分母,Derivative函式的作用是求導數,arctan的導數是1/(1+x^2),arth的導數是1/(1-x^2),所以可以根據n=p*q和z=p^2+q^2求出p和q。

from gmpy2 import *
from binascii import *
import sympy

c = 7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035
z = 32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482
n = 15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441

F1 = sympy.Symbol("F1")
F2 = sympy.Symbol("F2")
f1 = F1 * F2 - n
f2 = pow(F1, 2) + pow(F2, 2) - z

result = sympy.solve([f1, f2], [F1, F2])
# print(result)
p = result[3][0]
q = result[3][1]
phi_n = (p - 1) * (q - 1)
e = 65537
d = invert(e, int(phi_n))
m = pow(c, d, n)
hex_m = hex(m)
print(a2b_hex(hex_m[2:]))

1666148344(1)

四、RSA

  1. 題目中只給出了e、c、n、dp。

Crypto專項

  1. dp的含義是dp=d mod (p-1),可結合ed=1 mod n得到以下結果。

Crypto專項

  1. 遍歷k,求出p,就可以獲得明文。

import gmpy2 as gp

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751

for i in range(1, e): # 在範圍(1,e)之間進行遍歷
if (dp * e - 1) % i == 0:
if n % (((dp * e - 1) // i) + 1) == 0: # 存在p,使得n能被p整除
p = ((dp * e - 1) // i) + 1
q = n // (((dp * e - 1) // i) + 1)
phi = (q - 1) * (p - 1) # 尤拉定理
d = gp.invert(e, phi) # 求模逆
m = pow(c, d, n) # 快速求冪取模運算

print(m) # 10進位制明文
# print('------------')
# print(hex(m)[2:]) # 16進位制明文
# print('------------')
print(bytes.fromhex(hex(m)[2:])) # 16進位制轉文字

Crypto專項

五、RSA

  1. 附件是一個.enc和.key檔案。

Crypto專項

Crypto專項

  1. 利用線上工具將公鑰給解析出來。

Crypto專項

  1. 利用yafu對n進行分解,得到p和q。

Crypto專項

  1. 編寫指令碼求解。

Crypto專項

六、Dangerous RSA

  1. 題目給出n、e、c。

Crypto專項

  1. e的次數比較小,可以考慮這個為RSA中的低加密指數攻擊。

rsa 的加密 為 c = m ^ e mod n

當e 很小,n很大時,有兩種情況

(1) m ^ e 有可能小於 n 。 此時, c = m ^ e 。 密文 m = c 開e次方

(2)當 m ^ e > n 。 此時。 m ^ e = kn + c 。 k 是整數 。對 k 進行爆破,就能找到對應的m。

1665047327(1)

七、basic rsa

  1. 附件為一個py檔案。

Crypto專項

  1. 編寫指令碼得到m。

import gmpy2
from Crypto.Util.number import *

p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551
c = 27565231154623519221597938803435789010285480123476977081867877272451638645710
e = 65533
n = p * q
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
m = pow(c, d, n)
print(long_to_bytes(m))

Crypto專項

八、RSA

  1. 題目如下。

Crypto專項

Crypto專項

  1. 先看encrypt3,e_2=3很小,n_1^3=c_2+k*n_2使得k也不是很大,直接爆破k獲得n_1。

1666681887(1)

  1. 再看encrypt2,正常的大素數分解,獲得n_1。

1666682365(1)

  1. 最後看encrypt1和encrypt4,m1=hex(flag>>200).encode()=b'0x666c61677b3230366538353964'可以得到flag>>200 = 0x666c61677b3230366538353964 的位數是104,所以flag的位數位200+104=304位,即flag為304//8=38位長的字串,則m2 = str(hex(n))[20:].encode(),m2的位數為224位小於k的512位,所以m2=m%k其實是無效的,直接將m轉位元組即可。

from Crypto.Util.number import *
from gmpy2 import iroot, invert
from binascii import hexlify, unhexlify
from sympy.ntheory import totient

n_2 = 675835056744450121024004008337170937331109883435712066354955474563267257037603081555653829598886559337325172694278764741403348512872239277008719548968016702852609803016353158454788807563316656327979897318887566108985783153878668451688372252234938716250621575338314779485058267785731636967957494369458211599823364746908763588582489400785865427060804408606617016267936273888743392372620816053927031794575978032607311497491069242347165424963308662091557862342478844612402720375931726316909635118113432836702120449010
n_3 = 91294511667572917673898699346231897684542006136956966126836916292947639514392684487940336406038086150289315439796780158189004157494824987037667065310517044311794725172075653186677331434123198117797575528982908532086038107428540586044471407073066169603930082133459486076777574046803264038780927350142555712567
e_1 = 65537
e_2 = 3
c_1 = 47029848959680138397125259006172340325269302342762903311733700258745280761154948381409328053449580957972265859283407071931484707002138926840483316880087281153554181290481533
c_2 = 332431
c_3 = 11951299411967534922967467740790967733301092706094553308467975774492025797106594440070380723007894861454249455013202734019215071856834943490096156048504952328784989777263664832098681831398770963056616417301705739505187754236801407014715780468333977293887519001724078504320344074325196167699818117367329779609
m = 9530454742891231590945778054072843874837824815724564463369259282490619049557772650832818763768769359762168560563265763313176741847581931364
k = 8139616873420730499092246564709331937498029453340099806219977060224838957080870950877930756958455278369862703151353509623205172658012437573652818022676431

t = 0
tmp = c_2
while 1:
if iroot(tmp, 3)[1]:
n_1 = iroot(tmp, 3)[0]
print(n_1) #70406706457855863712635967741447303613971473150228480705119773604469794649140239446237334040048504811343327173817296308781190911727763110615393368497803655390445303946160971
print(t)
break
tmp += n_2
t += 1

p = 2224243981
q = 2732337821
r = 11585031296201346891716939633970482508158508580350404805965250133832632323150440185890235814142601827544669601048550999405490149435265122374459158586377571

phi = (p - 1) * (q - 1) * (r - 1)
d = invert(e_1, phi)
m1 = pow(c_1, d, n_1)
m1 = hex(m1)[2:]
m1 = unhexlify(m1)
m1 = hex(int(m1, 16))[2:]
m1 = unhexlify(m1)
flag1 = m1.decode()
flag2 = unhexlify(long_to_bytes(m))
print(flag1)
print(flag2)

1666683247(1)

九、

其他

一、Alice與Bob

  1. 根據題意,編寫程式碼,得到兩個素數101999,966233。

import math


def isPrime(n):
if n == 1 or n == 2:
return True
for i in range(2, int(math.sqrt(n))):
if n % i == 0:
return False
return True


a = 98554799767
for i in range(2, int(math.sqrt(a))):
if a % i == 0:
if isPrime(i) and isPrime(a / i):
print(i, a / i)

  1. 再將這兩個數字拼接起來,進行md5的雜湊計算,得出flag。

Crypto專項

二、這是base?

  1. 開啟txt檔案,裡面是一個字典和一段密文。

Crypto專項

  1. 看來本題的題意是將密文中的各個字母找到字典中對應的索引號,再去找到該索引號對應的base64標準表的字母,在進行base64解密即可,編寫指令碼得到flag。

import base64

dict = {0: 'J', 1: 'K', 2: 'L', 3: 'M', 4: 'N', 5: 'O', 6: 'x', 7: 'y', 8: 'U', 9: 'V', 10: 'z', 11: 'A', 12: 'B',
13: 'C', 14: 'D', 15: 'E', 16: 'F', 17: 'G', 18: 'H', 19: '7', 20: '8', 21: '9', 22: 'P', 23: 'Q', 24: 'I',
25: 'a', 26: 'b', 27: 'c', 28: 'd', 29: 'e', 30: 'f', 31: 'g', 32: 'h', 33: 'i', 34: 'j', 35: 'k', 36: 'l',
37: 'm', 38: 'W', 39: 'X', 40: 'Y', 41: 'Z', 42: '0', 43: '1', 44: '2', 45: '3', 46: '4', 47: '5', 48: '6',
49: 'R', 50: 'S', 51: 'T', 52: 'n', 53: 'o', 54: 'p', 55: 'q', 56: 'r', 57: 's', 58: 't', 59: 'u', 60: 'v',
61: 'w', 62: '+', 63: '/', 64: '='}

a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' # 標準表

c = 'FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw'

ds = '' # 把dict轉換成字串方便處理
for i in range(65):
ds += dict[i]

l = []
for i in range(len(c)):
l.append(ds.index(c[i])) # 無論換不換表,base64變換本身產生的6位二進位制數對應的十進位制數是不變的,這裡就是找到密文c的每個字元在dict表中鍵值

print(l) #l中存的是索引值(下標數字)

m1 = ''
for ll in l:
m1 += a[ll] # 找到l中所存的每個數字在標準的base64加密表中所對應的字元
print(m1) # m1是標準base64表編碼結果

m2 = base64.b64decode(m1) # 直接呼叫函式恢復出明文
print(m2)

1663249415(1)

相關文章