[ctfshow]ecc_mini

目录

1.题目

2.分析

3.解题

4.参考

1.题目

#ecc_mini.py:

from Crypto.Util.number import *
from secret import flag
flag=bytes_to_long(flag)
a =getPrime(256)
b =getPrime(256)
p =getPrime(256)
m1=int(str(flag)[:5])-4585
m2=int(str(flag)[5:])
#EllipticCurve([a1, a2, a3, a4, a6]) -- y^2+(a1)xy+(a3)y=x^3+(a2)x^2+(a4)x+(a6)
E = EllipticCurve(GF(p), [a, b])
X=E.lift_x(m1)
Y=7*X
m = E.random_point()
G = E.random_point()
k = getPrime(256)
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G
w2=m[0]*m2
print(f"p = {p}")
print(f"a = {a}")
print(f"b = {b}")
print(f"k = {k}")
print(f"E = {E}")
print(f'Y = {Y}')
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"w2 = {w2}")
'''
p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
a = 106105288190268015217241182934677375171023341761047638573248022053052499733117
b = 76170541771321874396004434442157725545076211607587599314450304327736999807927
k = 58155941823118858940343657716409231510854647214870891375273032214774400828217
E = Elliptic Curve defined by y^2 = x^3 + 34707491256665545391276236596452538912073367128507057339946181246439062354614*x + 4772744837719404570039488103932889286126236975047018081148463521123562429424 over Finite Field of size 71397796933602469825964946338224836258949974632540581233301840806613437378503
Y = (33237936857741483513705672980652927705102229733798436323453609986072499230366 : 52619411226266177137991318059937693955038910547834999771526408984808553907338 : 1)
c1 = (37414446283406201193977113266234367761786780230360175925999700345196415953455 : 17037724145039910971426670298726906655653040365428438334942732090559637519851 : 1)
c2 = (60560423732267272277570046154733119097475794979191838027420415113112056962844 : 54372226143125971429691267751299496959531971082475860532181772357190222938465 : 1)
w2 = 16315249811700998894876359855091105114973337718373913477026230968747515636405
'''

2.分析

这道题的数据给得很多,大部分的篇幅都用来数据的输出和呈现了,看起来应该不难。

这道题应该是利用ECC的常用的特性,信息被加密到一个点上,实际看来应该是把信息用一个点给锁住了,w2是加密后的结果,被用m的横坐标锁住了,我们只要能够求得m,就容易得到明文,而m的获得是ECC加密常见的题型,这题给的信息足够充足,能够直接得到m。

w2=m[0]*m2

在得到了m2之后,我们查看源代码,实际上我们已经获得了大部分的信息了,我们甚至可以尝试直接使用所获得的信息进行解密。

原文中有关信息的分布,信息主要在m2中:

m1=int(str(flag)[:5])-4585
m2=int(str(flag)[5:])

尝试解密:

import libnum
m2 = int(7196365442241205186856420688221367789171469258517476477)
print(libnum.n2s(m2))
#b'K"1\x0c]\xd9]\x99\xc6_u\xa0y>\t\x1c_is_it}'

我们看到已经有部分的明文泄露了,所以其实我们可以对前面5个数位进行爆破,但是这里有两种爆破方式,一种是直接爆破解密,将合理的值输出,另一种是根据原文代码进行爆破,先找到正确的m1,再进行解密。

3.解题

获得m点坐标,其ECC加密的原理如下:

C_1 - kC_2 = M + rkG - krG = M

p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
a = 106105288190268015217241182934677375171023341761047638573248022053052499733117
b = 76170541771321874396004434442157725545076211607587599314450304327736999807927
k = 58155941823118858940343657716409231510854647214870891375273032214774400828217


from Crypto.Util.number import *


E = EllipticCurve(GF(p), [a, b])
c1 = E(37414446283406201193977113266234367761786780230360175925999700345196415953455 , 17037724145039910971426670298726906655653040365428438334942732090559637519851)
c2 = E(60560423732267272277570046154733119097475794979191838027420415113112056962844 , 54372226143125971429691267751299496959531971082475860532181772357190222938465)

print(c1 - k * c2)

#m = (71304669061767049972885792894615651818794274529315856194992266286323237158881 : 10126770036343069593803252437914418057336213410278953515516757017939543175878 : 1)

获得m2:

m0 = R(71304669061767049972885792894615651818794274529315856194992266286323237158881)
w2 = R(16315249811700998894876359855091105114973337718373913477026230968747515636405)
p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
R = GF(p)


from Crypto.Util.number import *


E = EllipticCurve(GF(p), [a, b])
print(w2 // m0)


#m2 = 7196365442241205186856420688221367789171469258517476477

第一种爆破,直接爆破解密:

import libnum
m2 = int(7196365442241205186856420688221367789171469258517476477)

for i in range(10000,100000):
    m = m2 + i * 10 ** len(str(m2))
    try:
        flag = libnum.n2s(int(m)).decode()#可以用于滤除含不可见字符的字符串
        if '{' in flag: #保证flag形式合理
            print(flag)
    except:
        pass


#ctfshow{the_answer_is_it}

第二种爆破,根据原代码的设定进行相应爆破,先得到m1,再解码:

原代码:

X=E.lift_x(m1)
Y=7*X

据此进行爆破:
 

p = 71397796933602469825964946338224836258949974632540581233301840806613437378503
a = 106105288190268015217241182934677375171023341761047638573248022053052499733117
b = 76170541771321874396004434442157725545076211607587599314450304327736999807927
Y = E(33237936857741483513705672980652927705102229733798436323453609986072499230366,52619411226266177137991318059937693955038910547834999771526408984808553907338)

import libnum
E = EllipticCurve(GF(p), [a, b])
#爆破m1
for i in range(10000, 99999):
    try:
        x = E.lift_x(i - 4585)
        y = 7*x
        if y == Y:
            print(i)
            break
    except:
        pass
m2 = int(7196365442241205186856420688221367789171469258517476477)
plain = m2 + i * 10 ** len(str(m2))
flag = libnum.n2s(int(plain))
print(flag)
#m1 = 62428
#flag = b'ctfshow{the_answer_is_it}'

flag为:

ctfshow{the_answer_is_it}

4.参考

文章1文章2

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值