tutctf wp

动手能力太差了,难绷

RSA

题目

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
from Crypto.Util.number import getPrime, bytes_to_long
import math

FLAG = 'TUTCTF{???}'
victory_key = "TUTCTF"

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

def generate_parameters(bit_length=512):
p = getPrime(bit_length)
q = getPrime(bit_length)
n = p * q
e = 65537
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
s = p ** 4 + q ** 4
return n, e, d, s, p, q


def main():
n, e, d, s, p, q = generate_parameters()
flag = victory_encrypt(FLAG, victory_key).encode()
c = pow(bytes_to_long(flag), e, n)

with open('output.txt', 'w') as f:
f.write(f"n = {n}\n")
f.write(f"e = {e}\n")
f.write(f"c = {c}\n")
f.write(f"s = {s}\n")

print("[+] Parameters saved to output.txt")


if __name__ == "__main__":
main()

分析

已知p4+q4p^4 + q^4和p*q直接求pq就行
结果居然在这个套进去的弗吉尼亚卡了半天
当时连iroot都忘了,还手搓了一个

exp

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
from Crypto.Util.number import *
from gmpy2 import iroot

n = 88404336390052935295167907014990955167757899166459645006020564159910221950313103760744672095425046680977787806322104643113602241372187173741911921754830225380574290977520985329714483964734108589788286223669965444856353724037278541347276877433268175877986937451783914356003584010727646191451951063889248455609
e = 65537
c = 11921825186409298359079406916048192752767602192852391027241791193540838563492205016430418692802136940042065660220785320139908699089839204989955923648475022632803709791144611891680915190699364526974964681462990992432763033256899420495174369119948019155391667748721838548855253797865294424715858493207125261252
s = 22132256578806823997411210238808484780469981809371209041138582748325286114773081797359449254956289434027815102781847751566660330245563532030327073594906392050350502480761813167057219691372052865250833774891975836256799851265608403712175822132860992971312233187072699175930548398773550774537747747336997188361273018466118654290172956476269827800885378133620054325496862790981890907988859536668688826996940261310466429501167512388903117667233782399351835622719788747984955437789431901139660570839313478117275304708756873028209644328685542844890157184777151916692998517816399743210153407834925554864778286523140387691362

a2 = iroot(s + 2*n*n, 2)[0]
a = iroot(a2 + 2*n, 2)[0]
delt = iroot(a*a - 4*n, 2)[0]

q = (a + delt) // 2
p = a - q


d = inverse(e, (p-1)*(q-1))
m = pow(c, d, n)
rsa_flag = long_to_bytes(m).decode()

def vigenere_decrypt(ct, key):
out = []
ki = 0
for ch in ct:
if ch.isalpha():
base = ord('A') if ch.isupper() else ord('a')
k = ord(key[ki % len(key)].upper()) - 65 # 使用65代替97更严谨,对应 'A'
out.append(chr((ord(ch) - base - k) % 26 + base))
ki += 1
else:
out.append(ch)
return ''.join(out)

key = "TUTCTF"
flag = vigenere_decrypt(rsa_flag, key)
print("[+] Final Flag:", flag)

ecc

题目

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 Crypto.Util.number import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from random import randint
import hashlib
from sage.all import *
flag = b'TUTCTF{???}'

p = 146808027458411567

A = randint(1, p)
B = randint(1, p)

E = EllipticCurve(GF(p),[A,B])

G = E.random_point()

key = '???'
Q = key*G
print(f"p = {p}")
print(f"G = {G}")
print(f"Q = {Q}")

key = hashlib.sha256(str(key).encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
flag = pad(flag,16)
ciphertext = cipher.encrypt(flag)
print(f"ciphertext={ciphertext}")


# p = 146808027458411567
# G = (35813342313999718 : 66850728853227735 : 1)
# Q = (2399221355957408 : 125062289889696869 : 1)
# ciphertext=b'HmME\x08\xc5O\xa6\xab+\x0f\xbc\x90[]HR\x06\xf4\xa1\x84t\x8f@\xcf\x90\x97\xe3\xba:p/AxM-\xa3\xd3\xce\xb6?\x92\x85\xab\x97"\x04\xf9\xb1\x1b\x83L\xd3P\xd0V\x96569\'%\xb71'

分析

签到题,不会写代码,气笑了
p不大所以可以带入求出AB后直接用discrete_log函数尝试求解
记录一下语法知识点吧

  1. 创建曲线:
1
2
3
4
5
E = EllipticCurve(GF(p), [a, b])     #创建曲线y² = x³ + ax + b
E = EllipticCurve(GF(p), secp256k1) # 比特币/以太坊曲线
E = curves.SECP256R1() # NIST P-256
E = curves.Curve25519() # 现代密钥交换曲线
E = curves.Ed25519() # 现代签名曲线
  1. discret_log求解ecdlp:
    key = discrete_log(Q, G, operation='+')
    · Q: 目标元素
    · G: 群的生成元
    · operation=‘+’: 指定群运算为加法,计算 key 满足 Q = key・G

operation='*':乘法
operation='+':加法

exp

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
from sage.all import *
from Crypto.Util.Padding import unpad
import hashlib
from Crypto.Cipher import AES

p = 146808027458411567
c = b'HmME\x08\xc5O\xa6\xab+\x0f\xbc\x90[]HR\x06\xf4\xa1\x84t\x8f@\xcf\x90\x97\xe3\xba:p/AxM-\xa3\xd3\xce\xb6?\x92\x85\xab\x97"\x04\xf9\xb1\x1b\x83L\xd3P\xd0V\x96569\'%\xb71'
F = GF(p)
x1,y1 = F(35813342313999718), F(66850728853227735)
x2,y2 = F(2399221355957408), F(125062289889696869)


A = (y1**2 - y2**2 - x1**3 + x2**3) / (x1 - x2)
B = y1**2 - x1 ** 3 - A*x1
E = EllipticCurve(F, [A, B])

G = E(x1, y1)
Q = E(x2, y2)

key = discrete_log(Q, G, operation='+')
key = hashlib.sha256(str(key).encode()).digest()
print("AES Key:", key)

cipher = AES.new(key, AES.MODE_ECB)
plaintext_padded = cipher.decrypt(c)
plaintext = unpad(plaintext_padded, AES.block_size)

print(plaintext.decode())

ezrsa

题目

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

m = bytes_to_long(flag)
assert len(flag)==32
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537
c1 = p^m
c2 = pow(m,e,n)
print(f'n = {n}')
print(f'c1 = {c1}')
print(f'c2 = {c2}')
"""
n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601
""""

exp

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
from gmpy2 import *
from Crypto.Util.number import *
from sage.all import *

n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601
e = 65537
p = c1 ^^ 0
PR.<x> = PolynomialRing(Zmod(n))


def partial_prime_known_highbits(n, known_high, unknown_bits):

f = known_high * 2^unknown_bits + x
roots = f.small_roots(X=2^unknown_bits, beta=0.4,epsilon = 0.01)
for r in roots:
p = int(known_high * 2^unknown_bits + r)
if p and n % p == 0:
return p
return None
for i in range(0,256):
print(i)
p_high = p >> 256
p_high = p_high << 8
p_high = p_high + i
try:
p0 = partial_prime_known_highbits(n,p_high,248)
q = n // p0
if p0*q == n:
phi = int((p0-1)*(q-1))
d = inverse(e,phi)
m = pow(c2,d,n)
print(long_to_bytes(int(m)))
break
except:
continue


tutctf wp
https://ddanggui.top/2026/06/01/tutctf/
作者
ddanggui
发布于
2026年6月1日
许可协议