攻防世界crypto进阶区onetimepad

文章目录

    • content
    • writeup
    • summary

content

攻防世界 crypto 高手进阶区 4分题(动态分数) onetimepad 的

writeup

下载题目—解压zip文件
得到:一个密文文件和一段py
在这里插入图片描述
分别用notepad++打开
在这里插入图片描述
在这里插入图片描述
这里的关键是process(m,k)只是把m⊕k 赋值给了GF(2^256), 为了反平方,我们可以简单地平方255次
脚本(方法一):

c1 = 0xaf3fcc28377e7e983355096fd4f635856df82bbab61d2c50892d9ee5d913a07f
c2 = 0x630eb4dce274d29a16f86940f2f35253477665949170ed9e8c9e828794b5543c
c3 = 0xe913db07cbe4f433c7cdeaac549757d23651ebdccf69d7fbdfd5dc2829334d1b

k2 = c2 ^ str2num(fake_secret1)
k3 = c3 ^ str2num(fake_secret2)

kt = k3
for i in xrange(255):
    kt = process(kt, 0)

seed = kt ^ k2
print "SEED", seed
assert process(k2, seed) == k3

kt = k2
for i in xrange(255):
    kt = process(kt, 0)

k1 = kt ^ seed
print "K1", seed
assert process(k1, seed) == k2

m = k1 ^ c1
print `hex(m)[2:-1].decode("hex")`

脚本(方法二):

from Crypto.Util.number import bytes_to_long,long_to_bytes

K.<x>=GF(2L**256,modulus=x^256+x^10+x^5+x^2+1)

def polify(N):
    bN=list(bin(N)[2:])
    bN.reverse()
    return K(bN)

def unpolify(Poly):
    bN=Poly.polynomial().list()
    bN.reverse()
    return long(''.join([str(it) for it in bN]),2)

def solve():
    cip1=polify(0xaf3fcc28377e7e983355096fd4f635856df82bbab61d2c50892d9ee5d913a07f)
    cip2=polify(0x630eb4dce274d29a16f86940f2f35253477665949170ed9e8c9e828794b5543c)
    cip3=polify(0xe913db07cbe4f433c7cdeaac549757d23651ebdccf69d7fbdfd5dc2829334d1b)
    msg2=polify(bytes_to_long('I_am_not_a_secret_so_you_know_me'))
    msg3=polify(bytes_to_long('feeddeadbeefcafefeeddeadbeefcafe'))
    secret=cip2+msg2+(cip3+msg3).sqrt()
    key1=(cip2+msg2).sqrt()+secret
    msg1=cip1+key1
    return long_to_bytes(unpolify(msg1))

if __name__=='__main__':
    print 'flag{'+solve()+'}'

脚本(方法三):

from os import urandom

def process(m, k):
    tmp = m ^ k
    res = 0
    for i in bin(tmp)[2:]:
        res = res << 1;
        if (int(i)):
            res = res ^ tmp
        if (res >> 256):
            res = res ^ P
    return res

def keygen(seed):
    key = str2num(urandom(32))
    while True:
        yield key
        key = process(key, seed)

def str2num(s):
    return int(s.encode('hex'), 16)

src1 = 0xaf3fcc28377e7e983355096fd4f635856df82bbab61d2c50892d9ee5d913a07f
src2 = 0x630eb4dce274d29a16f86940f2f35253477665949170ed9e8c9e828794b5543c
src3 = 0xe913db07cbe4f433c7cdeaac549757d23651ebdccf69d7fbdfd5dc2829334d1b

fake_secret1 = "I_am_not_a_secret_so_you_know_me"
fake_secret2 = "feeddeadbeefcafefeeddeadbeefcafe"

k2 = src2 ^ str2num(fake_secret1)
k3 = src3 ^ str2num(fake_secret2)

kt = k3
for i in range(255):
    kt = process(kt, 0)

seed = kt ^ k2
print "SEED:", seed
assert process(k2, seed) == k3

kt = k2
for i in range(255):
    kt = process(kt, 0)

k1 = kt ^ seed
print "K1:", k1
assert process(k1, seed) == k2

m = k1 ^ src1
print hex(m)[2:-1].decode("hex")


summary

双手奉上大佬blog:
https://www.cnblogs.com/coming1890/p/13607557.html
(很好的解题过程及分析)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

M10++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值