网鼎杯2024crypto题解

目前只更新了青龙组的题目

CRYPTO1

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

p = getPrime(512)
q = getPrime(512)
n = p * q
d = getPrime(299)
e = inverse(d,(p-1)*(q-1))
m = bytes_to_long(flag)
c = pow(m,e,n)
hint1 = p >> (512-70)
hint2 = q >> (512-70)

print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"hint1 = {hint1}")
print(f"hint2 = {hint2}")

n = 114118679597315994458138232536029700477506764789782067073905766324635160145597602207164997807103187990046901850125798774503781767630201814025142189432534890147340404293319424524872695905368897290630698362559606549134377263394129199145835483978820237203114250882524438599220793209608842281879976692805855046971
e = 60930873636939710528141652371287627298970658591028170597199994159301433213017349592910581153194811053524011559886529831760967700162629319952838130973563991607758850226327915934518549584588693854388996425152821459866209334446088324204759334980239670811977086959854952233887459542997456604453766160444477603017
c = 11058775585296329544235824126670578486484201903851563493984057289075513008773878014007377223222464555346135675900619903617528838701118612201290486747980233570288315027654510774940371032813981282018787668864123759554297515664915358447425647424759926416629451915378248520432568536260902676664298855076689608823
hint1 = 884675140903190287932
hint2 = 1000130673738973880482

和领航杯2023密码学题目bd为重题

原来原来是论文题

有两种解法,一种是基于格规约的,另一种是基于小私指数

1
2
3
#reference
https://www.cnblogs.com/mumuhhh/p/17789591.html
https://dexterjie.github.io/2023/09/12/%E8%B5%9B%E9%A2%98%E5%A4%8D%E7%8E%B0/2023%E9%A2%86%E8%88%AA%E6%9D%AF/?highlight=%E9%A2%86%E8%88%AA%E6%9D%AF#bd

CRYPTO2

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# coding: utf-8
#!/usr/bin/env python2

import gmpy2
import random
import binascii
from hashlib import sha256
from sympy import nextprime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.number import long_to_bytes
from FLAG import flag
#flag = 'wdflag{123}'
def victory_encrypt(plaintext, key):
key = key.upper()
key_length = len(key)
plaintext = plaintext.upper()
ciphertext = ''

for i, char in enumerate(plaintext):
if char.isalpha():
shift = ord(key[i % key_length]) - ord('A')
encrypted_char = chr((ord(char) - ord('A') + shift) % 26 + ord('A'))
ciphertext += encrypted_char
else:
ciphertext += char

return ciphertext

victory_key = "WANGDINGCUP"
victory_encrypted_flag = victory_encrypt(flag, victory_key)

p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
a = 0
b = 7
xG = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
yG = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = (xG, yG)
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
h = 1
zero = (0,0)

dA = nextprime(random.randint(0, n))

if dA > n:
print("warning!!")

def addition(t1, t2):
if t1 == zero:
return t2
if t2 == zero:
return t2
(m1, n1) = t1
(m2, n2) = t2
if m1 == m2:
if n1 == 0 or n1 != n2:
return zero
else:
k = (3 * m1 * m1 + a) % p * gmpy2.invert(2 * n1 , p) % p
else:
k = (n2 - n1 + p) % p * gmpy2.invert((m2 - m1 + p) % p, p) % p
m3 = (k * k % p - m1 - m2 + p * 2) % p
n3 = (k * (m1 - m3) % p - n1 + p) % p
return (int(m3),int(n3))

def multiplication(x, k):
ans = zero
t = 1
while(t <= k):
if (k &t )>0:
ans = addition(ans, x)
x = addition(x, x)
t <<= 1
return ans

def getrs(z, k):
(xp, yp) = P
r = xp
s = (z + r * dA % n) % n * gmpy2.invert(k, n) % n
return r,s

z1 = random.randint(0, p)
z2 = random.randint(0, p)
k = random.randint(0, n)
P = multiplication(G, k)
hA = multiplication(G, dA)
r1, s1 = getrs(z1, k)
r2, s2 = getrs(z2, k)

print("r1 = {}".format(r1))
print("r2 = {}".format(r2))
print("s1 = {}".format(s1))
print("s2 = {}".format(s2))
print("z1 = {}".format(z1))
print("z2 = {}".format(z2))

key = sha256(long_to_bytes(dA)).digest()
cipher = AES.new(key, AES.MODE_CBC)
iv = cipher.iv
encrypted_flag = cipher.encrypt(pad(victory_encrypted_flag.encode(), AES.block_size))
encrypted_flag_hex = binascii.hexlify(iv + encrypted_flag).decode('utf-8')

print("Encrypted flag (AES in CBC mode, hex):", encrypted_flag_hex)

# output
# r1 = 28857061626266697731960297346547380130694223166851804642930502594650578288425
# r2 = 28857061626266697731960297346547380130694223166851804642930502594650578288425
# s1 = 81842916501936654327181596127464444170184582938148211467350979906270329843047
# s2 = 54199410087637342004207138894657653701426382978399616033659324046436549994669
# z1 = 114768147762808206397023700697633814229154932218327120646122869299219028759434
# z2 = 63513092260201266423877548128429517837199255134650637253201969399356248912467
# ('Encrypted flag (AES in CBC mode, hex):', u'51559ebae12fdd12e0e84df2baf07e3389b688398a71b62717fb77e0f6abdd40d848ee028b70681bc566ef2729d80b7a2778ad5b322b68501b6bbcef820b4719')

观察这一部分

1
2
3
4
5
6
7
8
9
10
11
12
13
def getrs(z, k):
(xp, yp) = P
r = xp
s = (z + r * dA % n) % n * gmpy2.invert(k, n) % n
return r,s

z1 = random.randint(0, p)
z2 = random.randint(0, p)
k = random.randint(0, n)
P = multiplication(G, k)
hA = multiplication(G, dA)
r1, s1 = getrs(z1, k)
r2, s2 = getrs(z2, k)

已知z1,z2,r1,r2,s1,s2

有方程组 联立消去 得到

提取出 得到

容易得到

1
2
3
import gmpy2
dA = (z2*s1-z1*s2)*gmpy2.invert(s2*r1-r2*s1,n)%n
print( dA )
1
2
#output
dA=10570650820062854135188945698682652204931348462301149982644765996528871376101

无脑解AES和古典即可,这个ai就能干

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
import binascii
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Hash import SHA256
from Crypto.Util.number import long_to_bytes

# 使用恢复的私钥 dA
dA = 10570650820062854135188945698682652204931348462301149982644765996528871376101
# 计算 AES 密钥
key = SHA256.new(long_to_bytes(dA)).digest()

# 输入你已经获得的加密数据
encrypted_flag_hex = u'51559ebae12fdd12e0e84df2baf07e3389b688398a71b62717fb77e0f6abdd40d848ee028b70681bc566ef2729d80b7a2778ad5b322b68501b6bbcef820b4719'

# 从十六进制字符串中提取 IV 和加密的标志
encrypted_data = binascii.unhexlify(encrypted_flag_hex)
iv = encrypted_data[:AES.block_size] # 前 16 字节是 IV
encrypted_flag = encrypted_data[AES.block_size:] # 剩下的是加密后的标志

# 创建 AES 解密器
cipher = AES.new(key, AES.MODE_CBC, iv)

# 解密并去填充
try:
decrypted_flag = unpad(cipher.decrypt(encrypted_flag), AES.block_size)
print("Decrypted flag:", decrypted_flag.decode('utf-8'))
except ValueError as e:
print("Decryption failed:", e)
1
2
#output
Decrypted flag: SDSRDO{2DZ35AN97NP3EY15602G02H5ZP50R287}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def victory_decrypt(ciphertext, key):
key = key.upper()
key_length = len(key)
plaintext = ''

for i, char in enumerate(ciphertext):
if char.isalpha():
shift = ord(key[i % key_length]) - ord('A')
decrypted_char = chr((ord(char) - ord('A') - shift) % 26 + ord('A'))
plaintext += decrypted_char
else:
plaintext += char

return plaintext

victory_key = "WANGDINGCUP"
t = "SDSRDO{2DZ35AN97NP3EY15602G02H5ZP50R287}"

print( victory_decrypt( t , victory_key ) )
1
2
#output
WDFLAG{2BF35AA97FC3CE15602D02B5FA50E287}

最后转成小写即可

1
print("WDFLAG{2BF35AA97FC3CE15602D02B5FA50E287}".lower())
1
2
#output
wdflag{2bf35aa97fc3ce15602d02b5fa50e287}