HECTF2022 Crypto 部分题解

 本次HECTF,由于学业繁忙,挑了些题目做一做。

 

流动的音符:♭♭♫♭♭§‖♭∮♭♯♩‖♭♪‖♩♫‖♭‖♭‖§♭‖♩‖♬♫♭‖‖‖♬∮‖¶♩♭‖♪‖♬♯♭♯♪‖¶¶‖♬♭♭‖♪‖♬♫§=

直接网页在线解密,得到EA>N?s:WZgTdPYbMSaYg

古典密码无非移位和替换,分析前面字母与HECTF的关系可以发现是变异凯撒,初始密钥=3,后面依次+1.最后得出flag。

 

ezrsa:

from Crypto.Util.number import *
from secret import flag
flag = b'xxx'
e = 114
m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
t = getPrime(1024)
n = p * q * t
p_=pow(p,2,n)
q_=pow(q,2,n)
c = pow(m,e,n)

print('p_=',p_)
print('q_=',q_)
print('c=',c)
print('n=',n)
#p_= 10660749010264526666955869622200514149424664070021154725214604278423033834800955315638637946982741577976025615843487738805576629855459529381681679497064453109727962183277768658053394103348827822686515016677449953958986089293779870089604784750116267441026319440135025236091029928565442799040007751858012409498271852333017388486644053877238274838173771344350870565886676055860728949042361028753924290647753862707042472944714140635484722345522648010064713004854479094986010632316750770118044301903260988074471243247031854872785324506292730778884664223412372663828159205320038546293395502275887356885181013870536857351801
#q_= 24900409366873586425973971191854411152048453357438215578406168704445779543895031579176888535442469919297663892450230816720758414920791049333275007446412352293152157437672026001378469357187698312455020558413101033543700131403373834030395855212901673914686297701313223697181049265286011127188695284002470629178098454764536315245968458622929902214839704674718996340182311301099900271312644919770585429288043854743210617868761990329037081770477261306489047429460937057125193231432195877922731165870197358946683698077175950756482605399815830687563398277515452842563143685190688865084064679712177247354049377034394880941369
#c= 946358882688806235743551077996671406469185038565566907261383734984318844703303437873183869084536703835433988817350857866089668970925835657856975155167500190428922521871327955274363186305180350899397478897928581580727458938934640786146518171503388507311655160765881370401217708135845031083189007308497775864484758699096082815479602777639307812516934937183952478316508418895341680335172973583094238147073379957772209947376051520041093030641369536800448737539973770258342422560893630082723217759837690008955748444973711508371077927468399703456466637348191192859278206925769696645636969358967735037470196395844215361527039288120664704552775460536654859848091685928057224735031528303041212702445718384890182474053295656578327780048497422707815820736647212902522526653039676698263673166412650104420869762547385554961873764933774143297622712766521201037469301912471740996998228799841957283759679784569638149555093498363791420486340
#n= 1677924010415009671349677258549532467848510897335579570922114838282842960143799964694977371357046837674443739542407516581076865550606801686170400793463690366665534118961173768008603133641864003317727610676872685077700753537755254540591236871020140458419596610210236431401477173114522177145982007059709616618279936170223104755776796458682957656555154039384483954754660803554302451221585280396378564648495919069459351016010016636012245082009946238467068412198769348889950331295680906811430325690102055808865038151762131291269197341984605959088829226733422023970618165958725486675321766767430347929319621215891165857544847088373700410007500868721335483070938971597851859953792409442485301373327127595552457801719192824050415833073999094005750868115932130442747899994421453654008731830580286370350900523295205445599466666709544075950517531382971246869745425091317996973135364990272852701046046315136273893166361180330563013617843

 

阅读代码,第一步无非就是通过开方得出p,q,然后得到t,从而得到phi(n)

先看p_=pow(p,2,n),展开便是p**2=p_+i*n,我们可以通过爆破得出p的值,q同理。

下面丢出脚本:

i = 0
while True:
    if gmpy2.iroot((p_ + i * n), 2)[1] == True:
        p =gmpy2.iroot((p_ + i * n), 2)[0]
        break
    i += 1
i = 0
while True:
    if gmpy2.iroot((q_ + i * n), 2)[1] == True:
        q =gmpy2.iroot((q_ + i * n), 2)[0]
        break
    i += 1
t=n//(p*q)

下面求出phi(n),本人的想法是这题直接顺利成章的出来。但发现逆元不存在。因此下面应该处理逆元不存在的问题。

phii=(t-1)*(q-1)
if p%(q*t)==0:
    phi=phii*p
else:
    phi=phii*(p-1)
b=math.gcd(e,phi)  #求出公约数
bb=e//b        
a=gmpy2.invert(bb,phi)   #由于bb和phi互素,逆元可求
mm=pow(c,a,n)       #c=m**e mod n  可知c**a=m**(b*bb*a)modn 由于bb*a=1 mod phi所以m**b=c**a mod n

 

下面对mm开方就行

给出完整脚本:

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



p_= 10660749010264526666955869622200514149424664070021154725214604278423033834800955315638637946982741577976025615843487738805576629855459529381681679497064453109727962183277768658053394103348827822686515016677449953958986089293779870089604784750116267441026319440135025236091029928565442799040007751858012409498271852333017388486644053877238274838173771344350870565886676055860728949042361028753924290647753862707042472944714140635484722345522648010064713004854479094986010632316750770118044301903260988074471243247031854872785324506292730778884664223412372663828159205320038546293395502275887356885181013870536857351801
q_= 24900409366873586425973971191854411152048453357438215578406168704445779543895031579176888535442469919297663892450230816720758414920791049333275007446412352293152157437672026001378469357187698312455020558413101033543700131403373834030395855212901673914686297701313223697181049265286011127188695284002470629178098454764536315245968458622929902214839704674718996340182311301099900271312644919770585429288043854743210617868761990329037081770477261306489047429460937057125193231432195877922731165870197358946683698077175950756482605399815830687563398277515452842563143685190688865084064679712177247354049377034394880941369
c= 946358882688806235743551077996671406469185038565566907261383734984318844703303437873183869084536703835433988817350857866089668970925835657856975155167500190428922521871327955274363186305180350899397478897928581580727458938934640786146518171503388507311655160765881370401217708135845031083189007308497775864484758699096082815479602777639307812516934937183952478316508418895341680335172973583094238147073379957772209947376051520041093030641369536800448737539973770258342422560893630082723217759837690008955748444973711508371077927468399703456466637348191192859278206925769696645636969358967735037470196395844215361527039288120664704552775460536654859848091685928057224735031528303041212702445718384890182474053295656578327780048497422707815820736647212902522526653039676698263673166412650104420869762547385554961873764933774143297622712766521201037469301912471740996998228799841957283759679784569638149555093498363791420486340
n= 1677924010415009671349677258549532467848510897335579570922114838282842960143799964694977371357046837674443739542407516581076865550606801686170400793463690366665534118961173768008603133641864003317727610676872685077700753537755254540591236871020140458419596610210236431401477173114522177145982007059709616618279936170223104755776796458682957656555154039384483954754660803554302451221585280396378564648495919069459351016010016636012245082009946238467068412198769348889950331295680906811430325690102055808865038151762131291269197341984605959088829226733422023970618165958725486675321766767430347929319621215891165857544847088373700410007500868721335483070938971597851859953792409442485301373327127595552457801719192824050415833073999094005750868115932130442747899994421453654008731830580286370350900523295205445599466666709544075950517531382971246869745425091317996973135364990272852701046046315136273893166361180330563013617843
e = 114

i = 0
while True:
    if gmpy2.iroot((p_ + i * n), 2)[1] == True:
        p =gmpy2.iroot((p_ + i * n), 2)[0]
        break
    i += 1
i = 0
while True:
    if gmpy2.iroot((q_ + i * n), 2)[1] == True:
        q =gmpy2.iroot((q_ + i * n), 2)[0]
        break
    i += 1
t=n//(p*q)
phii=(t-1)*(q-1)
if p%(q*t)==0:
    phi=phii*p
else:
    phi=phii*(p-1)
b=math.gcd(e,phi)  #求出公约数
bb=e//b
a=gmpy2.invert(bb,phi)   #由于bb和phi互素,逆元可求
mm=pow(c,a,n)       #c=m**e mod n  可知c**a=m**(b*bb*a)modn 由于bb*a=1 mod phi所以m**b=c**a mod n
m=gmpy2.iroot(mm,b)[0]
print(long_to_bytes(m))

 

#sage
p=235322474717419
a=0
b=8856682
k=
E = EllipticCurve(GF(p), [a, b])
P = E.random_point()
P.order()==p
Q=k*P
aes_key=k
print("P:",P)
print("Q:",Q)
#P=E(180571547161769,227820272156445)
#Q=E(76765539897460,69715189045993)

 

从python脚本可以看出是aes ecb解密

key通过sagemath计算获取

我们知道,Q=kP,想要直接求k是很难的。但这题规定了P.order==p所以可以通过smart‘s attack

#sagemath
def SmartAttack(P,Q,p):
    E = P.curve()
    Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])

    P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
    for P_Qp in P_Qps:
        if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
            break

    Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
    for Q_Qp in Q_Qps:
        if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
            break

    p_times_P = p*P_Qp
    p_times_Q = p*Q_Qp

    x_P,y_P = p_times_P.xy()
    x_Q,y_Q = p_times_Q.xy()

    phi_P = -(x_P/y_P)
    phi_Q = -(x_Q/y_Q)
    k = phi_Q/phi_P
    return ZZ(k)
p=235322474717419
a=0
b=8856682
E = EllipticCurve(GF(p), [a, b])
P=E(180571547161769,227820272156445)
Q=E(76765539897460,69715189045993)
n = SmartAttack(P, Q, p)
n

 

得到的n就是我们key

下面直接简简单单的解密就ok了

给出解密脚本

from Crypto.Cipher import AES
import base64
from Crypto.Util.number import *

def pad(text):
    while len(text) % 16 != 0:
        text += b' '
    return text

def pad_key(key):
    while len(key) % 16 != 0:
        key += b' '
    return key
aes_key=b'152675955744921'
aes = AES.new(pad_key(aes_key), AES.MODE_ECB)
enc='bXaw/g8fD7taMjlL/OyqUJluD6dZI5GkZb9RrE5GQk8='
dec=base64.b64decode(enc)
flag=aes.decrypt(pad(dec))
print(flag)

over,由于比较忙,其他题目没怎么看,有机会再看吧,毕竟孩子只是个大一密码新手,呜呜~

 

posted @ 2022-11-07 16:32  m0feng  阅读(199)  评论(0编辑  收藏  举报