AES-CBC 练习
原创
内存余响
内存余响
内存余响
2026年10月15日 23:02
江西
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
AES是分组密码,一次只能加密16字节
模式加密原理:
C\0 = E(P\_0 ⊕ IV)
C\_1 = E(P\_1 ⊕ C\_0)
C\_2 = E(P\_2 ⊕ C\_1)
...
C\_n = E(P\_n ⊕ C\)
P\_i对明文进行分组,每组16字节,E()是AES加密函数(用key加密一个16字节块)
第一组和16字节随机的初始向量进行异或后加密得到 第一组密文,之后第一组密文代替初始向量进行异或,依次类推,形成链式
解密
P\0 = D(C\_0) ⊕ IV
P\_i = D(C\_i) ⊕ C\
D(),AES解密函数(用key解密一个16字节块)
在题目中我们得到的消息msg可能是任意长度,所以要切分成16字节一块,不足16字节的用PKCS#7填充(缺一字节\x01,两字节\x02\x02, 依次类推\x0a表示缺10字节,十一\x0b x11,十六\x10 x16)
我们来写一个例题
!/usr/bin/python
from Crypto.Cipher import AES
import binascii
from Crypto.Util.number import bytes\_to\_long
from flag import flag
from key import key
iv = flag.strip(b'd0g3{').strip(b'}')
LENGTH = len(key)
assert LENGTH == 16
hint = os.urandom(4) \* 8
print(bytes\_to\_long(hint)^bytes\_to\_long(key))
msg = b'Welcome to this competition, I hope you can have fun today!!!!!!'
def encrypto(message):
aes = AES.new(key,AES.MODE\_CBC,iv)
return aes.encrypt(message)
print(binascii.hexlify(encrypto(msg))[-32:])
'''
56631233292325412205528754798133970783633216936302049893130220461139160682777
b'3c976c92aff4095a23e885b195077b66'
'''
我们知道了msg,先把他们进行分组,这里刚好是64字节
我们现在得到的这个是10进制56631233292325412205528754798133970783633216936302049893130220461139160682777
转成16进制
m=hex(56631233292325412205528754798133970783633216936302049893130220461139160682777)
print(m)
0x7d3424647d3424647d3424647d34246419044357064341081e5b4901045b5119
0x 7d342464 7d342464 7d342464 7d342464 19044357 06434108 1e5b4901 045b5119
└────────── 高 16 字节 ──────────┘ └────────── 低 16 字节 ──────────┘
7d342464重复4次
hint = os.urandom(4) \* 8,hint是4字节重复8次
我们看到前面都是有一样的,异或时短数左边补0
hint: r r r r r r r r
key : 0 0 0 0 k k k k
结果: r r r r (r^k)(r^k)(r^k)(r^k)
└高16┘ └─────低16─────┘
现在我们知道这个key只影响低16位,现在这个重复的7d342464是r,hint的低16字节就是
7d342464 7d342464 7d342464 7d342464
结果的低16字节和hint的低16字节进行异或,我们就可以把这个key求出来
19044357 ^ 7d342464 = 64306733
06434108 ^ 7d342464 = 7b77656c
1e5b4901 ^ 7d342464 = 636f6d65
045b5119 ^ 7d342464 = 796f757d
key = 643067337b77656c636f6d65796f757d
key = bytes.fromhex('643067337b77656c636f6d65796f757d')
print(key)
得到key是d0g3{welcomeyou}
根据题目
binascii.hexlify(encrypto(msg))[-32:]
msg用AES加密之后转hex取最后32个,就是最后一组密文
msg (64 字节)
│
│ PKCS#7 填充 + 16 字节 \x10
▼
80 字节明文(4 组 P0~P3)
│
│ AES-CBC 加密
▼
80 字节密文(4 组 C0~C3)
│
│ binascii.hexlify()
▼
160 个 hex 字符
│
│ [-32:]取最后 32 个
▼
32 个 hex 字符 = 16 字节 = C3(最后一组密文)
也就是说最后一组密文AES解密之后得到的和原来我们已知的P3异或得到
解题脚本
from pwn import xor
from Crypto.Cipher import AES
from Crypto.Util.number import bytes\_to\_long, long\_to\_bytes
msg = b'Welcome to this competition, I hope you can have fun today!!!!!!'
m = [msg[i:i+16] for i in range(0, len(msg), 16)] #分成了4分,16字节一份
hint = 56631233292325412205528754798133970783633216936302049893130220461139160682777
key = xor(long\_to\_bytes(hint),b'}4$d'\*8)[-16:]
c = bytes.fromhex('3c976c92aff4095a23e885b195077b66')
aes = AES.new(key,AES.MODE\_ECB)
for mi in m[::-1]:
c = xor(aes.decrypt(c),mi)
print(c)
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论