相关原理
占坑(大概不填了)
测试代码
使用aes测试(理论上所有使用CBC的分组加密都有这个问题)
readme
- 适用范围:CBC分组加密密码,PKCS#5或PKCS#7 padding方式
try_dec
输入bytes的待解密文本,输出True为可通过unpad,输出False为不通过unpad
- 如果给iv可以解密所有密文,否则不能解密第一组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| from Crypto.Cipher import AES from Crypto.Util import number from Crypto.Util.strxor import strxor import os
def pad(plain): ''' using pkcs#7 standard ''' to_pad = 16 - len(plain) % 16 return plain + number.long_to_bytes(to_pad)*to_pad
def unpad(cipher): if cipher[-1] > 16 or cipher[-1] == 0: raise Exception cipher_len = len(cipher) for i in range(cipher_len - 1, cipher_len - cipher[-1] - 1, -1): if cipher[i] != cipher[-1]: raise Exception return cipher[:-cipher[-1]]
iv = os.urandom(16) key = os.urandom(16)
aes = AES.new(key, AES.MODE_CBC, iv) plain_text = b"VT-x or AMD-v virtualization must be enabled"
padded = pad(plain_text) cipher = aes.encrypt(padded)
def try_dec(cipher): try: x = aes.decrypt(cipher) plain = unpad(x) return True except: return False
cipher = iv+cipher
block_len = 16
cipher_len = len(cipher) groups = [ cipher[i:i + block_len] for i in range(0, cipher_len, block_len) ] groups_len = len(groups) res = b''
for group_num in range(groups_len-2, -1, -1): cipher_array = bytearray(cipher) intermediary = bytearray(block_len) flag = 0 for i in range(256): cipher_array[block_len * group_num + block_len - 1] = i test_cipehr = bytes(cipher_array) if try_dec(test_cipehr): if i == cipher[block_len * group_num + block_len - 1]: continue intermediary[block_len - 1] = 1 ^ i flag = 1 if not flag: intermediary[block_len - 1] = 1 ^ cipher[block_len * group_num + block_len - 1] for i in range(block_len - 2, -1, -1): fill_value = block_len - i for j in range(i+1, block_len): cipher_array[block_len * group_num + j] = intermediary[j] ^ fill_value for j in range(256): cipher_array[block_len * group_num + i] = j test_cipehr = bytes(cipher_array) if try_dec(test_cipehr): intermediary[i] = fill_value ^ j res = strxor(groups[group_num], bytes(intermediary)) + res cipher = cipher[:-block_len]
print(res)
|