crypto

我和小蓝鲨的秘密

嗯,自己算p和q,剩下的就交给gpt了

n可直接分解,就得到了p和q

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
from gmpy2 import *
from PIL import Image
from libnum import n2s,s2n
import numpy as np


p = 160216064374859
q = 186431677583461
e = 0x10001

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

# 加载加密的图像数据
encrypted_array = np.load("encrypted_image.npy", allow_pickle = True)
h, w, _ = encrypted_array.shape

# 初始化解密后的图像数组
decrypted_array = np.zeros((h, w, 3), dtype=np.uint8)

for i in range(h):
for j in range(w):
r_enc, g_enc, b_enc = encrypted_array[i, j]

# RSA 解密
r = pow(r_enc, d, n)
g = pow(g_enc, d, n)
b = pow(b_enc, d, n)

decrypted_array[i, j] = [r, g, b]

decrypted_img = Image.fromarray(decrypted_array, "RGB")
decrypted_img.save("decrypted_flag.jpg")

得到解密后的图片

ChaCha20-Poly1305

这个题的难点是key是用base92加密的,我们遇到不会的加密先直接用随波逐流一把梭

image-20241118210256958

然后将代码塞给gpt或者自己写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Cipher import ChaCha20_Poly1305
import binascii

# 提供密钥、nonce、密文和标签
key = binascii.unhexlify('173974535637a5ef30a116b03d00bd2fe751951ca3eaa62daec2b8f5ca5b6135')
nonce = binascii.unhexlify('d8ebeedec812a6d71240cc50') # 填入实际的nonce
ct = binascii.unhexlify('20408b9fc498063ad53a4abb53633a6a15df0ddaf173012d620fa33001794dbb8c038920273464e13170e26d08923aeb') # 填入实际的密文
tag = binascii.unhexlify('70ffcc508bf4519e7616f602123c307b') # 填入实际的认证标签

# 创建ChaCha20-Poly1305解密器
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)

# 解密并验证标签
try:
plaintext = cipher.decrypt_and_verify(ct, tag)
print("解密成功:", plaintext.decode())
except ValueError:
print("验证失败或密文被篡改")

蓝鲨的费马

https://www.bilibili.com/video/BV1Sh41177Rm/这讲了个类似的题

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

l=(p^q%n+q^p%n)%n
l1=p^q%n=p
l2=q^p%n=q
l=p+q
phi=n+1-q-p


l= d+p+q
c^d%n=m
l= d+p+q
d=l-(p+q)
c^[l-(p+q)]%n=m
c^l*c^[-(p+q)]%n=m

c^(p+q)%n=?
因为 phi=(p-1)*(q-1)
phi=pq+1-p-q
phi=n+1-(p+q)
根据欧拉定理
a^phi%n=1
c^phi%n=1
c^[n+1-(p+q)]%n=1
c^(n+1)*c^[-(p+q)]%n=1
c^(n+1)*c^[-(p+q)]%n*c^(p+q)%n=1*c^(p+q)%n

结论:c^(n+1)%n=c^(p+q)%n
c^l*c^[-(n+1)]%n=m
c^[l-(n+1)]%n=m
c^(l-n-1)%n=m
1
2
3
4
5
6
7
8
from Crypto.Util.number import long_to_bytes

c= 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n= 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak= 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881

m=pow(c,(leak-n-1),n)
print(long_to_bytes(m))

以上我自己写的,大佬写的正式的在这https://blog.csdn.net/qq_42557115/article/details/143810738

小蓝鲨的数学题

离散对数求解问题

用sagemath运行

1
2
3
4
5
6
7
8
m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193
a=7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
G=Zmod(2**512)
m1=G(m)
c1=G(a)
print(ZZ(discrete_log(c1,m1)))

//print(long_to_bytes())

小蓝鲨的密码

image-20241120203758354

刚开始看到有张图片,而且压缩包还需要密码,因为是misc的图片题

结果解压密码就是图片名bluesharkinfo

我们解密后得到了一个字典

image-20241120204613747

我们打开最开始的txt文档,发现是一个用aes加密的密文,而且刚好给了字典,那key肯定在字典里面

image-20241120204738912

我们发现字典里有个isctf2024,那我们尝试一下

https://tool.oschina.net/encrypt/

image-20241120205132999

小蓝鲨的方程

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
from Cryptodome.Util.number import *
from random import *
from gmpy2 import *
import uuid
flag1='ISCTF{'+str(uuid.uuid4())+'}'

m1=bytes_to_long(flag1.encode())
def get_p():
BITS = 256
bits = 777
oder = 4
a = randint(1 << bits, 1 << bits + 1)
p=getPrime(BITS)
p1 = p**oder+a
return p,p1
p,p1=get_p()
s=getPrime(1024)
q=getPrime(512)
n=p*q**4
e=65537
c1=pow(s,e,n)
c=pow(s**3+1,m1,s**5)
print("c1=",c1)
print("c =",c)
print("n =",n)
print("p1 =",p1)

求p和q

已知p1=p^4^+a ,p^4^≫a ,那我们对p^4^开四次方根,然后再往前找素数,即可解得p和q

1
2
3
4
5
6
7
8
9
10
11
12
13
def crack(n, p1):
for i in trange(10000):
test = iroot(p1, 4)[0] - i
if not is_prime(test):
continue
else:
q = iroot(n // test, 4)
if q[1]:
q = q[0]
print()
print("found!")
return test,q

当然,我们还能使用simpy内置方法prevprime() 用于得到给定数字n的前一个素数

求s

我们知道

1
2
3
n=p*q**4
e=65537
c1=pow(s,e,n)

所以我们套欧拉函数

φ(n)=φ(p*q^4^)=φ(p)∗φ(q^4^)=(p−1)∗(q^4^−q^3^)

然后正常求rsa就能得到s

1
2
3
phi = (p-1)*(q**4 - q**3)
d = invert(e, phi)
s = pow(c1, d, n)

求m

参考DLP (158/Crypto) · Hackademia Writeups

一开始先不考虑模数,根据二项式定理,我们有一般式:

(n+1)^m^=n^m^+m∗n^m^−1+…+m∗n+1

在本题中n=s^3^,此时,我们对这个式子模n^2^,会发现除了最后两项,其他项都被模掉了,所以

(n+1)^m^ mod n^2^=m∗n+1 mod n^2^

这样我们就求出了m=((c%n2)−1 )/n

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Cryptodome.Util.number import *
from gmpy2 import iroot
from sympy import prevprime,discrete_log
c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436
n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111
p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553

p4=iroot(p1,4)[0]
p=prevprime(p4)
while n%p!=0:
p=prevprime(p)
q=iroot(n//p,4)[0]


s=pow(c1,inverse(65537,(p-1)*(q**4-q**3)),n)
n=s**3
m=(c%n**2-1)//n
print(long_to_bytes(m))