AES_CBC已知一部分+爆破

本文详细介绍了如何解决一个基于AES的签到挑战。首先解释了AES_CBC和AES_ECB的区别,然后通过分析已知信息,确定了需要爆破的部分。利用Python编写代码生成可能的密钥字典,并通过ECB模式解密找到正确的密钥。最终,通过解密和异或操作还原了初始的IV,即flag。整个过程展示了密码学在CTF挑战中的应用。
摘要由CSDN通过智能技术生成

一个AES签到

前提

AES_CBC 是什么

在这里插入图片描述

同时需要知道AES_ECB是什么

就是上面的图去掉异或和iv

最后就是 AES常用的块长度了 128bit

题目

from Crypto.Cipher import AES
import binascii
import hashlib
from secret import flag

assert flag[:5] == "flag{" and flag[-1:] == "}"

key = b"J1fx2g1jDak1c***"
l = len(key)

message = b"I have had my invitation to this world's festival, and thus my life has been blessed" + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]

iv = flag[5:-1]
message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = "utf-8")
aes = AES.new(key, AES.MODE_CBC, iv)
print(binascii.hexlify(aes.encrypt(message)))
#******************************************************************************************************************************************************6ece036e495d363b647d7f2749c4c2f3dd78f8637b

思路

已知

部分key (有爆破的意思

前半部分明文+后半部分与key有关 (明确爆破了

再看密文 只有后42个hex(168bit

那么分析一下哈

先看密文

40+128==168

再算一下 明文长度

bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = "utf-8")

(这个的值是b'\x02\x02'不要问我怎么知道的哈 你没有python环境么???

84+10+2

96 (char

96*8

768/128 (bit/bit

6块

不知道你们能不能看明白哈 (反正给你标单位了

过程

根据分析发现不用任何填充 正好6块

所以 已知第六组对应的明文和密文 (当然得爆破

既然爆破就得知道正确与否 怎么验证呢

用密文多出的 40bit 进行验证

OK!那么就真知道了第六组对应的明文和密文

密文使用key通过AES_ECB 解密 得到一个中间值

这个中间值再与明文异或 就得到第六次加密的 iv 即第五次的密文

按照这个思路往前推 即可知道 最开始的iv 即flag

代码实现

1.首先爆破 先有字典

import string
with open("keytable.txt","wb+") as file :
    for i in string.printable[:62]:
        for j in string.printable[:62]:
            for k in string.printable[:62]:
                key = "J1fx2g1jDak1c"
                key+=i
                key+=j
                key+=k
                file.write(bytes(key.encode()))
                file.write(b"\n")

2.爆破

from Crypto.Cipher import AES
import binascii
import hashlib
from tqdm import tqdm

def xor(m: bytes, c: bytes): 
    return bytes([i ^ j for i, j in zip(m, c)])

file = open("keytable.txt","rb+")
enc = b"5d363b647d7f2749c4c2f3dd78f8637b"
five_part = binascii.unhexlify(b"6ece036e49")

pbar = tqdm(range(238328))
for i in file:
    key = i[:16]
    aes = AES.new(key, AES.MODE_ECB)
    dec = aes.decrypt(binascii.unhexlify(enc))
    six = b"ssed"
    six += binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]
    six += b'\x02\x02'
    xor_result = xor(six,dec)
    pbar.update(1)
    if five_part in xor_result:
        print(binascii.hexlify(xor_result))  #用于做验证
        print(key)
        print(xor_result)
        break
file.close()

输出

b'd7318ea3725b337f2c26056ece036e49'
'J1fx2g1jDak1c7s4'
b'\xd71\x8e\xa3r[3\x7f,&\x05n\xce\x03nI'

3.还原iv

from Crypto.Cipher import AES

def xor(m: bytes, c: bytes):
    return bytes([i ^ j for i, j in zip(m, c)])

message = b"I have had my invitation to this world's festival, and thus my life has been ble"
key = b"J1fx2g1jDak1c7s4"
enc = b'\xd71\x8e\xa3r[3\x7f,&\x05n\xce\x03nI'
aes = AES.new(key, AES.MODE_ECB)

for i in range(int(len(message)/16)):
    enc = xor(aes.decrypt(enc),message[len(message)-16*(i+1):len(message)-16*i])
    print(enc)

输出

b'0\x07S\xbf^\xd9\x1d\xd3\xfcT\xf4I\xa6\x9b\xf3\xa0'
b'\xc6\xd6Tc\xb6\x08\x9d\xa9H4\xa1Z\xfb\xeb\x08\x8f'
b'\xb1 \t8\x0b\x9b\x18d\xa48\xf2;\r\xb1 \xc4'
b'\x8c\xf3\xfa\xce\x93fB\xb9\xb2\xad\x01\x9d\x1a6\x80\x11'
b'welcome_1234_igd'

特别鸣谢

8神 yyds
(https://github.com/davidcheyenneone/CTF)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值