2023羊城杯Crypto
首发于
DexterJie’Blog
Danger_RSA
题目:
from Crypto.Util.number import *
m = bytes_to_long(flag)
def get_key(a, nbit):
assert a >= 2
while True:
X = getRandomInteger(nbit // a)
s = getRandomRange(pow(2, a ** 2 - a + 4), pow(2, a ** 2 - a + 5))
p = X ** a + s
if isPrime(p):
return (p, s)
p, s = get_key(a, 1024)
q, t = get_key(a, 1024)
N = p * q
e = s * t
c = pow(m, e, N)
print("N =", N)
print("e =", e)
print("c =", c)
# N =
# e = 11079917583
# c =
根据 p , q p,q p,q的生成方式可知 p = x 4 + s , q = y 4 + t p = x^4+s,q = y^4+t p=x4+s,q=y4+t
根据 e e e的比特大小判断出 a = 4 , s = 17 b i t , t = 17 b i t a=4,s = 17bit,t = 17bit a=4,s=17bit,t=17bit
把 e e e分解后得到 e = 3 × 7 2 × 19 × 691 × 5741 e = 3\times7^2 \times 19 \times 691 \times 5741 e=3×72×19×691×5741
选出合适的乘积作为 s , t s,t s,t
∴ p = x 4 + s , q = y 4 + t \therefore p =x^4 + s,q = y^4 + t ∴p=x4+s,q=y4+t, p ≈ x 4 , q ≈ y 4 p \approx x^4,q \approx y^4 p≈x4,q≈y4
则 n ≈ ( x y ) 4 ⟶ x y = n 1 4 n \approx(xy)^4 \longrightarrow xy = n^{\frac{1}{4}} n≈(xy)4⟶xy=n41
得到 x y xy xy之后
联立 n = ( x 4 + s ) ( y 4 + t ) n = (x^4+s)(y^4+t) n=(x4+s)(y4+t)与 x × y = x y x\times y = xy x×y=xy
解出 x , y x,y x,y,这里要注意的是,s,t要选合适,才有整数解,多试试
然后就能出p,q了,发现 e e e和 ϕ ( n ) \phi(n) ϕ(n)不互素
处理一下即可
exp:
from Crypto.Util.number import *
import gmpy2
n = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766
s = 120561
t = 91903
ab = int(gmpy2.iroot(n,4)[0])
# var('a b')
# f1 = a*b-ab
# f2 = ab^4 + a^4*t + b^4*s + s*t - n
# ans = solve([f1,f2],[a,b])
# print(ans)
a = 47783641287938625512681830427927501009821495321018170621907812035456872958654
b = 44416071018427916652440592614276227563515579156219730344722242565477265479486
p = a^4 + s
q = b^4 + t
assert p*q == n
phi = (p-1)*(q-1)
# print(gcd(e,phi))
# 21
d = gmpy2.invert(e // 21,p - 1)
m_21 = pow(c,d,p)
#求出m的21次方
e = 21
R.<x>=PolynomialRing(Zmod(p))
f = x^e - m_21
f = f.monic()
mps = f.roots()
for i in mps:
flag=long_to_bytes(int(i[0]))
if b'DASCTF' in flag:
print(flag)
一般flag没有填充的情况下,会小于p,所以用 p , q p,q p,q单独作公钥求解
求解出 m 21 ≡ c d m o d p m^{21} \equiv c^{d} \mod p m21≡cdmodp
再用多项式环求根
参考:2023 CryptoCTF wp by lingfeng (medium分类——1)_c_ling_feng的博客-CSDN博客
Easy_3L
题目:
from gmpy2 import *
from Crypto.Util.number import *
from secret import flag
m = bytes_to_long(flag)
def get_key():
p = getPrime(1400)
f = getRandomNBitInteger(1024)
while True:
q = getPrime(512)
if gcd(f, q) != 1:
continue
else:
break
h = (invert(f, p) * q) % p
return p, h
def encrypt1(m):
a = getPrime(250)
b = getRandomNBitInteger(240)
n = getPrime(512)
seed = m
s = [0] * 6
s[0] = seed
for i in range(1, 6):
s[i] = (s[i - 1] * a + b) % n
return s
def encrypt2(msg, p, h):
s = getRandomNBitInteger(512)
c = (s * h + msg) % p
return c
s = encrypt1(m)
print("S1 =", s[1])
print("S2 =", s[2])
print("S4 =", s[4])
print("S5 =", s[5])
p, h = get_key()
c = encrypt2(s[3], p, h)
print("p =", p)
print("h =", h)
print("c =", c)
# S1 =
# S2 =
# S4 =
# S5 =
# p =
# h =
# c =
没给出S3,要先把S3求出来,然后就是LCG求解
已知 c ≡ s h + m s g m o d p ⟶ c = s h + m s g + k p c \equiv sh+msg \mod p \longrightarrow c = sh + msg +kp c≡sh+msgmodp⟶c=sh+msg+kp
∴ m s g = c − s h − k p \therefore msg = c - sh -kp ∴msg=c−sh−kp
构造这样的格
exp:
#sage
from Crypto.Util.number import *
import gmpy2
p = 25886434964719448194352673440525701654705794467884891063997131230558866479588298264578120588832128279435501897537203249743883076992668855905005985050222145380285378634993563571078034923112985724204131887907198503097115380966366598622251191576354831935118147880783949022370177789175320661630501595157946150891275992785113199863734714343650596491139321990230671901990010723398037081693145723605154355325074739107535905777351
h = 2332673914418001018316159191702497430320194762477685969994411366563846498561222483921873160125818295447435796015251682805613716554577537183122368080760105458908517619529332931042168173262127728892648742025494771751133664547888267249802368767396121189473647263861691578834674578112521646941677994097088669110583465311980605508259404858000937372665500663077299603396786862387710064061811000146453852819607311367850587534711
c = 20329058681057003355767546524327270876901063126285410163862577312957425318547938475645814390088863577141554443432653658287774537679738768993301095388221262144278253212238975358868925761055407920504398004143126310247822585095611305912801250788531962681592054588938446210412897150782558115114462054815460318533279921722893020563472010279486838372516063331845966834180751724227249589463408168677246991839581459878242111459287
Ge = Matrix(ZZ,[
[-p,0,0],
[-h,1,0],
[c,0,2^512]
])
for i in Ge.LLL():
if abs(i[-1]) == 2^512:
S3 = i[0]
S1 = 28572152986082018877402362001567466234043851789360735202177142484311397443337910028526704343260845684960897697228636991096551426116049875141
S2 = 1267231041216362976881495706209012999926322160351147349200659893781191687605978675590209327810284956626443266982499935032073788984220619657447889609681888
S4 = 9739918644806242673966205531575183334306589742344399829232076845951304871478438938119813187502023845332528267974698273405630514228632721928260463654612997
S5 = 9755668823764800147393276745829186812540710004256163127825800861195296361046987938775181398489372822667854079119037446327498475937494635853074634666112736
output = [S1,S2,S3,S4,S5]
t = []
for i in range(1,len(output)):
t.append(output[i]-output[i-1])
T = []
for i in range(1,len(t)-1):
T.append(t[i+1]*t[i-1] - t[i]**2)
m = []
for i in range(len(T)-1):
mm = gmpy2.gcd(T[i],T[i+1])
m.append(int(mm))
# print(m)
for i in m:
if isPrime(i):
a = gmpy2.invert(t[0],i) * t[1] % i
b = output[1] - a*output[0] % i
a_ = gmpy2.invert(a,i)
seed = a_ * (output[0]-b) % i
print(long_to_bytes(seed))
signinCrypto
from random import *
from Crypto.Util.number import *
from Crypto.Cipher import DES3
from flag import flag
from key import key
from iv import iv
import os
import hashlib
import secrets
K1= key
hint1 = os.urandom(2) * 8
xor =bytes_to_long(hint1)^bytes_to_long(K1)
print(xor)
def Rand():
rseed = secrets.randbits(1024)
List1 = []
List2 = []
seed(rseed)
for i in range(624):
rand16 = getrandbits(16)
List1.append(rand16)
seed(rseed)
for i in range(312):
rand64 = getrandbits(64)
List2.append(rand64)
with open("task.txt", "w") as file:
for rand16 in List1:
file.write(hex(rand16)+ "\n")
for rand64 in List2:
file.write(hex((rand64 & 0xffff) | ((rand64 >> 32) & 0xffff) << 16) + "\n")
Rand()
K2 = long_to_bytes(getrandbits(64))
K3 = flag[:8]
KEY = K1 + K2 + K3
IV=iv
IV1=IV[:len(IV)//2]
IV2=IV[len(IV)//2:]
digest1 = hashlib.sha512(IV1).digest().hex()
digest2 = hashlib.sha512(IV2).digest().hex()
digest=digest1+digest2
hint2=(bytes_to_long(IV)<<32)^bytes_to_long(os.urandom(8))
print(hex(bytes_to_long((digest.encode()))))
print(hint2)
mode = DES3.MODE_CBC
des3 = DES3.new(KEY, mode, IV)
pad_len = 8 - len(flag) % 8
padding = bytes([pad_len]) * pad_len
flag += padding
cipher = des3.encrypt(flag)
ciphertext=cipher.hex()
print(ciphertext)
# 334648638865560142973669981316964458403
# 0x62343937373634656339396239663236643437363738396663393438316230353665353733303939613830616662663633326463626431643139323130616333363363326631363235313661656632636265396134336361623833636165373964343533666537663934646239396462323666316236396232303539336438336234393737363465633939623966323664343736373839666339343831623035366535373330393961383061666266363332646362643164313932313061633336336332663136323531366165663263626539613433636162383363616537396434353366653766393464623939646232366631623639623230353933643833
# 22078953819177294945130027344
# a6546bd93bced0a8533a5039545a54d1fee647007df106612ba643ffae850e201e711f6e193f15d2124ab23b250bd6e1
重点是求KEY
和IV
观察代码,能猜测出,K1
,IV
,长度为8,
说明xor =bytes_to_long(hint1)^bytes_to_long(K1)
,hint1的高位没有受影响
输出long_to_bytes(xor)
,能够得到hint1 = b'\xfb\xc2' * 8
随即能出K1 = b"dasctfda"
K2
通过随机数求得
给出的是rand64[16:32]+rand64[48:64]
随机数的生成机制: 通过生成32bit的数进行拼接或者移位(大佬教的)
如果要生成16bit的数,是先生成32bit再取这个数的高16位
如果要生成64bit的数,先生成两个32bit的数x1
,x2
,再进行拼接x2||x1
本题中,因为两次seed是一样的,所以rand16
就是x1
的前16位,后面输出的rand16
是x2
的前16位
而rand64 = x2[:16] || rand64[16:32] || x1[:16] || rand64[48:64]
这样就有了全部rand64
,一共312个rand64
K3
前七位是DASCTF{
,最后一位不太确定
又因为hint2=(bytes_to_long(IV)<<32)^bytes_to_long(os.urandom(8))
,说明IV
的前面32bit不受影响
直接打印出,得到b'GWHT'
,注意到给出的那一段数据是两端重复数据拼接在一起的。
说明IV1 = IV2 = b'GWHT'
,
∴
\therefore
∴IV = b'GWHTGWHT'
exp:
from Crypto.Util.number import *
from Crypto.Cipher import DES3
from extend_mt19937_predictor import ExtendMT19937Predictor
predictor = ExtendMT19937Predictor()
xor = 334648638865560142973669981316964458403
# print(long_to_bytes(xor))
hint1 = b'\xfb\xc2' * 8
K1 = long_to_bytes(bytes_to_long(hint1) ^ xor)
# print(K1)
# K1 = b'dasctfda'
hint2 = 22078953819177294945130027344
# print(long_to_bytes(hint2))
K1 = b"dasctfda"
IV = b"GWHTGWHT"
f = open("task.txt",'r')
data = []
for i in f.readlines():
data.append(eval(i))
data1 = data[:624]
data2 = data[624:]
data3 = []
for i in data2:
b = (i >> 16) & 0xffff
d = i & 0xffff
data3.append(d)
data3.append(b)
for i,j in zip(data1,data3):
t = (i << 16) + j
predictor.setrandbits(t,32)
K2 = long_to_bytes(predictor.predict_getrandbits(64))
# print(K2)
K3 = b"DASCTF{"
c = "a6546bd93bced0a8533a5039545a54d1fee647007df106612ba643ffae850e201e711f6e193f15d2124ab23b250bd6e1"
c = bytes.fromhex(c)
for i in range(2**8):
KEY = K1 + K2 + K3 + long_to_bytes(i)
try:
mode = DES3.MODE_CBC
des3 = DES3.new(KEY, mode, IV)
flag = des3.decrypt(c)
if b'DASCTF{' in flag:
print(flag)
except:
continue
esyRSA——复现
from gmpy2 import invert
from md5 import md5
from secret import p, q
e = ?????
n = p*q
phi = (p-1)*(q-1)
d = invert(e, phi)
ans = gcd(e,phi)
print n, e, d
print "Flag: DASCTF{%s}" %md5(str(p + q)).hexdigest()
"""
n =
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
"""
发现这个n是有重复部分的,把重复部分删去后是正确的n
n=80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
∵ e d ≡ 1 m o d ϕ ( n ) \because ed \equiv 1 \mod \phi(n) ∵ed≡1modϕ(n)
$\longrightarrow ed = k\phi(n) + 1\$
同除 e × ϕ ( n ) e \times \phi(n) e×ϕ(n)
⟶ d ϕ ( n ) = k e + 1 e × ϕ ( n ) \longrightarrow \frac{d}{\phi(n)} = \frac{k}{e} + \frac{1}{e\times \phi(n)} ⟶ϕ(n)d=ek+e×ϕ(n)1
∵ ϕ ( n ) ≈ n \because \phi(n) \approx n ∵ϕ(n)≈n
∴ 上式 ⟶ d n ≈ k e \therefore 上式 \longrightarrow \frac{d}{n} \approx \frac{k}{e} ∴上式⟶nd≈ek
对 d n \frac{d}{n} nd进行连分数展开,得到的一串分数的分母很可能就是e
exp:
#sage
import hashlib
n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
c = continued_fraction(Integer(d) / Integer(n))
i = 1
while 1:
k = int(c.numerator(i)) #取连分数的分子
e = int(c.denominator(i)) #取连分数的分母
#计算kphi
if (e * d - 1) % k == 0 and len(str(e)) == 5:
phi = (e * d - 1) // k
p_q = n - phi + 1
print("p+q=",p_q)
print("e=",e)
# e = 13521
print("k=",k)
# k = 2384
var('p q')
f1 = p * q - n
f2 = p + q - p_q
sol = solve([f1,f2],[p,q])
print(sol)
break
else:
i += 1
p = 7920625690369490250766357750388349704260128405941822835255851274284409978206593795103040446837018619894098452542488850045009467407103749792461438242280929
q = 10181341212828413853336916619161138854377885230386496425058202154486415709366161346816273366144505351043947477469664133317598479763451392984403646602585037
flag = "DASCTF{" + hashlib.md5(str(p+q).encode()).hexdigest() + '}'
print(flag)
另外一种用格的思路解决
∵ e d ≡ 1 m o d p h i \because ed \equiv 1 \mod phi ∵ed≡1modphi
∴ e d = k p h i + 1 ⟶ e d = k ( n − p − q + 1 ) + 1 \therefore ed = kphi + 1 \longrightarrow ed = k(n - p - q + 1) + 1 ∴ed=kphi+1⟶ed=k(n−p−q+1)+1
e d = k n − k ( p + q − 1 ) + 1 ed = kn - k(p+q-1)+1 ed=kn−k(p+q−1)+1
k ( p + q − 1 ) − 1 = k n − e d k(p+q-1)-1 = kn -ed k(p+q−1)−1=kn−ed
构造格
规约后能得到e,再求k(p+q-1)
和ed - 1
的公因数得到k
exp:
import hashlib
n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
Ge = Matrix(ZZ,[
[2^512 , d],
[0 , n]]
)
L = Ge.LLL()[0]
e = abs(L[0]) // 2^512
k = gcd(e*d - 1,L[1]+1)
p_q = (L[1]+1) // k + 1
flag = "DASCTF{" + hashlib.md5(str(p_q).encode()).hexdigest() + '}'
print(flag)
MCeorpkpleer
题目:
from Crypto.Util.number import *
from secret import flag
def pubkey(list, m, w):
pubkey_list = []
for i in range(len(e_bin)):
pubkey_list.append(w * list[i] % m)
return pubkey_list
def e_cry(e, pubkey):
pubkey_list = pubkey
encode = 0
for i in range(len(e)):
encode += pubkey_list[i] * int(e[i]) % m
return encode
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = getPrime(64)
m = bytes_to_long(flag)
c = pow(m, e, n)
e_bin = (bin(e))[2:]
list = [pow(3, i) for i in range(len(e_bin))]
m = getPrime(len(bin(sum(list))) - 1)
w = getPrime(64)
pubkey = pubkey(list, m, w)
en_e = e_cry(e_bin, pubkey)
print('p = {}\n'
'n = {}\n'
'c = {}\n'
'pubkey = {}\n'
'en_e = {}'.format((p >> 435) << 435, n, c, pubkey, en_e))
'''
p =
n =
c =
pubkey =
en_e = 31087054322877663244023458448558
'''
给出p
的高位,coppersmith梭出p
。
需要求一下e
观察加密发现,list
是固定的,因为len(e_bin)==64
而且pubkey
的第一位就是w
又 ∵ p u b k e y i ≡ l i s t i × w m o d m \because pubkey_i \equiv list_i × w \mod m ∵pubkeyi≡listi×wmodm
∴ k m = l i s t i × w − p u b k e y i \therefore km = list_i \times w-pubkey_i ∴km=listi×w−pubkeyi
通过这个,求出几个km
,再求公因数,经过验证即可求得m = 4522492601441914729446821257037
然后感觉是解背包加密$c = (pubkey_1×e_1 \mod m) + \dots + (pubkey_{64}×e_{64}\mod m) $
构造格
(
1
0
0
…
0
0
k
e
y
1
0
1
0
…
0
0
k
e
y
2
0
0
1
…
0
0
k
e
y
3
⋮
⋮
⋮
⋱
⋮
⋮
⋮
0
0
0
…
1
0
k
e
y
64
0
0
0
…
0
1
c
0
0
0
…
0
0
p
)
\begin{pmatrix} 1 & 0 & 0 & \dots & 0 & 0 & key_1\\ 0 & 1 & 0 & \dots & 0 & 0 & key_2\\ 0 & 0 & 1 & \dots & 0 & 0 & key_3\\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots\\ 0 & 0 & 0 & \dots & 1 & 0& key_{64}\\ 0 & 0 & 0 & \dots & 0 & 1 & c\\ 0 & 0 & 0 & \dots & 0 & 0 & p \end{pmatrix}
100⋮000010⋮000001⋮000………⋱………000⋮100000⋮010key1key2key3⋮key64cp
正确结果卡在中间,一开始没发现,以为是自己思路错了。草!!!!!!
exp:
from Crypto.Util.number import *
import gmpy2
phigh =
N =
enc =
R.<x> = PolynomialRing(Zmod(n))
f = phigh + x
root = f.small_roots(X = 2^435,beta = 0.4)
if root:
p = phigh + int(root[0])
# print(p)
q = N // p
mod =
pubkey =
c =
n = len(pubkey)
Ge = Matrix(ZZ,n+2,n+2)
for i in range(n):
Ge[i,i] = 1
Ge[i,-1] = pubkey[i]
Ge[-2,-2] = 1
Ge[-2,-1] = c
Ge[-1,-1] = mod
for i in Ge.LLL():
if i[-1] == 0:
tmp = i[:-2]
ans = ''
for j in tmp:
if abs(j) == 0:
ans += '0'
if abs(j) == 1:
ans += '1'
e = int(ans,2)
if isPrime(e) and e.bit_length() == 64:
print(e)
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(enc,d,N)
print(long_to_bytes(int(m)))
下次一定看清楚www
另外一种解法是利用上超递增序列list
∵ c = ( p u b k e y 1 × e 1 m o d m ) + ⋯ + ( p u b k e y 64 × e 64 m o d m ) \because c = (pubkey_1×e_1 \mod m) + \dots + (pubkey_{64}×e_{64}\mod m) ∵c=(pubkey1×e1modm)+⋯+(pubkey64×e64modm)
把 p u b k e y ≡ w × l i s t pubkey \equiv w \times list pubkey≡w×list代入
∴ c = ( w × l i s t 1 × e 1 m o d m ) + ⋯ + ( w × l i s t 64 × e 64 m o d m ) \therefore c = (w \times list_1 \times e_1 \mod m) + \dots + (w \times list_{64} \times e_{64} \mod m) ∴c=(w×list1×e1modm)+⋯+(w×list64×e64modm)
∴ c ≡ w ( l i s t 1 × e 1 + ⋯ + l i s t 64 × e 64 ) m o d m \therefore c \equiv w(list_1 \times e_1 + \dots +list_{64}\times e_{64} ) \mod m ∴c≡w(list1×e1+⋯+list64×e64)modm
c × w − 1 ≡ l i s t 1 × e 1 + ⋯ + l i s t 64 × e 64 m o d m c \times w^{-1} \equiv list_1 \times e_1 + \dots +list_{64}\times e_{64} \mod m c×w−1≡list1×e1+⋯+list64×e64modm
list
是个超递增序列
exp:
from Crypto.Util.number import *
c = 31087054322877663244023458448558
mod = 4522492601441914729446821257037
w = 18143710780782459577
c = c * inverse(w,mod) % mod
list1 = [pow(3, i) for i in range(64)]
m = ''
for i in list1[::-1]:
if c >= i:
m += '1'
c -= i
else:
m += '0'
e = int(m[::-1],2)
print(e)
# e =15960663600754919507
XOR贯穿始终
先核心价值观解码得到压缩包的密钥:C0ngr4tulati0n5_y0u_fou^d_m3
拿到题目,以及私钥文件
from gmpy2 import gcd
from Crypto.Util.number import getPrime
from secret import enflag
p = getPrime(512)
q = getPrime(512)
n = q * p
phi = (p - 1) * (q - 1)
e = getPrime(17)
assert gcd(e, phi) == 1
# 以上信息生成了私钥文件,但文件被损坏了你能提取有用信息吗
c = pow(enflag, e, n)
print('c = ' + str(c))
'''
c = 91817924748361493215143897386603397612753451291462468066632608541316135642691873237492166541761504834463859351830616117238028454453831120079998631107520871612398404926417683282285787231775479511469825932022611941912754602165499500350038397852503264709127650106856760043956604644700201911063515109074933378818
'''
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALmtMy+2uH1ZtbIL
SuiAukFthyQRH5mp7UmLyzZQkdg9zEP9/5tgffikQ7ytx5kHySHnazgAO1sOzmYE
N4Axlev6uafiP8B1Eij97v5VkYJ1I9e3mtBNheTbXKoT8op+ASQ1fQaF4A8UzLuW
eZeZI8JTH/SH+bolAK3kiZXDFdkTAgMBAAECgYEAl067LaC7Cvs2A5cMPhfYsESv
IgcKN1CwW4Sd3u8dSphhgu7TgyzIuvwxbuo2g1BC6WwKhaI6vGN+csfw6nh98GEn
/p3D0huNroAYvf/DRRB9UnHdttX7wB+Mv3P0RBDWHgBiCDVvHFuFUV78cIs0tnbn
jxjU07aPV2XRC3AfA2ECQQDqWUNPVg3i6vTyHCL7EGkbeUheYpAAfcKCQrxjc5+5
X6A+XtgHAA1JHwykPlCpHUOmlA85DJF1ejuoImzlgRLJAkEAytTCnQF+MN2r1gaA
UETZyj5qMYT7Th8zKEVVVJjDawLnuX4usJ2FyRnjCkk86U75QSJhw5mMc0QnG25u
Gz3++w==
-----END PRIVATE KEY-----
私钥文件base64解密再转16进制
根据(PKCS1) RSA 公私钥 pem 文件解析 - 知乎 (zhihu.com)
提取到n,p,q。然后解密。中间那段绿色的不太明白代表什么意思,求师傅教教。后面了解到那个是d
解出来的结果和压缩包密钥异或一下才是真的flag。当时想到异或,但是把字符拿来异或了,卡了几分钟才做出来的导致痛失三血www
exp:
from Crypto.Util.number import *
import gmpy2
n = 0xb9ad332fb6b87d59b5b20b4ae880ba416d8724111f99a9ed498bcb365091d83dcc43fdff9b607df8a443bcadc79907c921e76b38003b5b0ece660437803195ebfab9a7e23fc0751228fdeefe5591827523d7b79ad04d85e4db5caa13f28a7e0124357d0685e00f14ccbb9679979923c2531ff487f9ba2500ade48995c315d913
e = 0x10001
p = 0xcad4c29d017e30ddabd606805044d9ca3e6a3184fb4e1f332845555498c36b02e7b97e2eb09d85c919e30a493ce94ef9412261c3998c7344271b6e6e1b3dfefb
q = 0xea59434f560de2eaf4f21c22fb10691b79485e6290007dc28242bc63739fb95fa03e5ed807000d491f0ca43e50a91d43a6940f390c91757a3ba8226ce58112c9
c = 91817924748361493215143897386603397612753451291462468066632608541316135642691873237492166541761504834463859351830616117238028454453831120079998631107520871612398404926417683282285787231775479511469825932022611941912754602165499500350038397852503264709127650106856760043956604644700201911063515109074933378818
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(int(m)))
a = b'C0ngr4tulati0n5_y0u_fou^d_m3'
flag = long_to_bytes(bytes_to_long(a) ^ int(m))
print(flag)