一个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)