AES-CBC基础练习
本文最后更新于37 天前,其中的信息可能已经过时,如有错误请发送邮件到 matter_lmoon5731@outlook.com

CBC的运算过程都是在字节的前提下运算的

CBC加密过程为随机选取一个16位的字节vi,和一个key值。

第一轮

利用异或将vi和明文的前16位字节进行异或

然后利用key对异或的结果进行加密

第二轮

将第一轮的结果与明文16-32(也就是第二组16位字节)进行异或

在利用key对异或的结果进行加密

依次类推

最终将全部的加密结果进行拼接

通过他的加密过程决定了,不论是明文,key,还是vi都必须是整除16.

明文不足16的倍数要进行填充,key和vi不是16的倍数直接报错

题目

import os
from Crypto.Util.number import *
from Crypto.Cipher import AES
from secret import flag, key
from Crypto.Util.Padding import pad
assert(len(flag) == 38)
assert flag[:5] == b'flag{' and flag[-1:] == b'}'
assert(len(key) == 16)
def padding(msg):
  tmp = 16 - len(msg) % 16
  pad = format(tmp, '02x')
  return bytes.fromhex(pad * tmp) + msg
message = padding(flag)
hint = bytes_to_long(key) ^ bytes_to_long(message[:16])
message = pad(message, 16, 'pkcs7')
IV = os.urandom(16)

encryption = AES.new(key, AES.MODE_CBC, iv=IV)
enc = encryption.encrypt(message)
print('enc =', enc.hex())
print('hint =', hex(hint)[2:])
# enc = 1ce1df3812668ce0bccd86c146cc56989681e128edd0676f5d26e01abdee90c860e22a5a491f94ac5ca3ab02242740fb8c35a3b60ea737ca0d2662fba2b0e299
# hint = 32393f4e3c3c4f3e323a512a5356437d

题目分析

对于题目发现flag==38是16的2倍余6,也就是差10个字节。所以它利用padding函数对明文进行了填充,使其满足16的倍数。

hint是key与messages[:16]的异或结果。由padding知道它补充了10个字节的 \x0a(02x的16进制的字节)。其次我们知道了flag前5个字节为flag{。也就是说现在只剩第16个字节不知道了。

后面就是随机获取IV(不信的话可以自己运行一下),然后利用key, AES.MODE_CBC, iv=IV创建了一个encryption的AES-CBC工具,然后调用encryption.encrypt对messages进行加密

解题思路

对于AES-CBC加密,我们如果知道了他的key,vi那么这个题目是不是就可以直接接出来了。应为我们如果知道了这两个值就可以建造一个与加密一模一样的AES-CBC工具,encryption,然后我们利用这个函数直接调用encryption.decrypt进行解密就可以了。

那么有了这个想法,我们可以发现hint是不是知道了,明文的前16个字节是不是也知道前15位了。那么我们接下来是不是就是去求解vi,和key了.

对于key的求法将hint与messages[:16]进行异或,这个时候会发现mssages最后一个不知道,我们可以随便给他一个字1,2,3都可以。这个题目的攻击点就是爆破这个字节——–注意要是字节形式的。其次要对enc和hint的格式进行转化。—————–异或的格式要求应该知道吧。

在得到key的前提下,我们接下来就要去得到vi。这个时候我们要知道

对于一把锁来说,他的钥匙是不是只有一把,

那么对于加密函数来说它的加密和解密的vi是不是对应的也是唯一的。

那么我们就可以构造一个AES-CBC工具来进行反推vi。很合理吧,我有锁了那么我就可以去找钥匙了,

但是注意vi的作用范围只限制于第一块加密

因此我们要加密的必须是只有16字节,并且已知密文的。——enc的前16字节

encryption = AES.new(key, AES.MODE_CBC, iv=bytes(16))
      di = encryption.decrypt(enc_list[0])
      vi = bytes([pad[i] ^ di[i] for i in range(16)])

得到vi后我们直接构造新的AES-CBC工具去直接解密完整的enc.然后得到flag。

你肯会对这两个构造不是很理解

你要记住你要先找到钥匙,在去开锁—-钥匙都没有是开不了锁的

当然以上的基础是在第16位明文有字节的情况下,接下来你要做的就是去爆破那一个字节 一个字节占8个bit位也就是 256

plaintext = unpad(plaintext_padded, 16)[10:]

对于这个代码他的作用是直接利用unpad去查看你的后10位是不是可读(应为题目的填充是填在前面的你可以运行验证一下)。不是的话他就会报错然后try结束执行except,except执行continue跳过本次循环,执行下一次。


from Crypto.Util.Padding import unpad
from Crypto.Util.number import *
from Crypto.Cipher import AES
hint='32393f4e3c3c4f3e323a512a5356437d'
hint=int(hint,16)
enc='1ce1df3812668ce0bccd86c146cc56989681e128edd0676f5d26e01abdee90c860e22a5a491f94ac5ca3ab02242740fb8c35a3b60ea737ca0d2662fba2b0e299'
enc=bytes.fromhex(enc)
enc_list = [enc[i:i + 16] for i in range(0, len(enc), 16)]
for a in range(256):
  #pad = b'\x0a' * 10 + b'flag{' + bytes(a)
  pad = b'\x0a' * 10 + b'flag{' + bytes([a])
  key = hint ^ bytes_to_long(pad)
  key = long_to_bytes(key, 16)
  try:
      encryption = AES.new(key, AES.MODE_CBC, iv=bytes(16))
      di = encryption.decrypt(enc_list[0])
      vi = bytes([pad[i] ^ di[i] for i in range(16)])
      # 用列表推导式更简洁
      aes_cbc_real = AES.new(key, AES.MODE_CBC, iv=vi)
      plaintext_padded = aes_cbc_real.decrypt(enc)
      plaintext = unpad(plaintext_padded, 16)[10:]
      if plaintext[:5] == b'flag{' and plaintext[-1:] == b'}':
          print(plaintext)
  except Exception as e:
      continue

建议

此外对于一些for循环的编写如果你是写一行直接写完那没有问题应为它的基础就是数组,不用在append但是如果你是给他展开写的你要特别注意它的append是不是真的是一个一个加入的。其次就要是要注意它所需要的类型是什么样的。

这个代码先对着这个思路自己敲一遍,不会的不要直接问ai要脚本,我已经把知识点拆解的还算比较细了,直接问它这个知识点应该如何编写,当然当你块没有耐心的时候可以叫ai给你代码做一个全方面检查。还是一样自己敲一遍率一遍感觉这个没必要在复制

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇