Лишний символы в списке

Всем привет!

Я переписываю некоторый код из PHP на Python и столкнулся с такой проблемой, мой код:

key_longs = [170, 71, 107, 76, 96, 150, 29, 197, 242, 164, 75, 84, 212, 215, 74, 190]
content = [165, 171, 188, 243, 150, 242, 158, 103, 131, 84, 239, 147, 235, 81, 135, 61, 70, 0, 173, 155, 78, 246, 203, 0, 14, 68, 137, 156, 179, 226, 166, 27, 99, 119, 143, 53, 230, 39, 206, 104, 108, 113, 103, 230, 213, 163, 243, 243, 78, 91, 4, 204, 98, 175, 46, 215, 198, 129, 98, 94, 30, 124, 102, 114, 133, 168, 215, 112, 86, 255, 233, 22, 120, 81, 106, 90, 218, 192, 134, 153, 169, 223, 178, 193, 208, 41, 188, 108, 190, 146, 84, 53, 63, 94, 40, 18]

decrypted = aes_decrypt(bytearray_decode(key_longs), bytearray_decode(content))


# print(list(decrypted)) в резльтате даст - [33, 133, 150, 210, 16, 208, 230, 191, 21, 35, 249, 102, 67, 22, 195, 125, 145, 84, 18, 218, 129, 217, 6, 20, 58, 106, 103, 176, 4, 59, 106, 83, 94, 185, 145, 98, 232, 125, 53, 0, 44, 220, 168, 248, 176, 156, 172, 136, 31, 139, 8, 0, 0, 0, 0, 0, 0, 0, 43, 73, 45, 46, 1, 0, 12, 126, 127, 216, 4, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8]

def aes_decrypt(secretKey, encoded):
     initVector = encoded[0:16]
     data = encoded[16:]
     key = bytearray(secretKey.encode('latin-1'))
     vector = bytearray(initVector.encode('latin-1'))
     decryptor = AES.new(key, AES.MODE_CBC, vector)
     decoded = decryptor.decrypt(data.encode("latin-1"))
     return decoded

def bytearray_decode(arrays):
    out = []
    for d in arrays:
        out.append(chr(d))
    return "".join(out)

И проблема в том, что у меня decrypted больше, чем нужно.

Мне нужно получить :[33,133,150,210,16,208,230,191,21,35,249,102,67,22,195,125,145,84,18,218,129,217,6,20,58,106,103,176,4,59,106,83,94,185,145,98,232,125,53,0,44,220,168,248,176,156,172,136,31,139,8,0,0,0,0,0,0,0,43,73,45,46,1,0,12,126,127,216,4,0,0,0]

А у меня почему то заполняется лишними восмерками. Подозреваю, что где то с кодировкой что-то не так.

Есть идеи?


Ответы (1 шт):

Автор решения: GrAnd

Это padding (выравнивание) до границы блока в 16 байт. Надо просто отрезать столько с конца, сколько указано в последнем байте. И согласно PKCS эти все байты будут идентичны. У AES всегда в конце есть выравнивание, даже когда исходные данные кратны 16 (в этом случае в конце будут 16 байт из чисел 16).

Код для отрезания:

decrypted = decrypted[:-decrypted[-1]]

И вообще, все эти игры с кодировками (всякие encode/chr) здесь абсолютно не нужны (и могут быть даже вредны).

from Crypto.Cipher import AES

def aes_decrypt(secretKey, encoded):
     initVector = encoded[0:16]
     data = encoded[16:]
     decryptor = AES.new(secretKey, AES.MODE_CBC, initVector)
     decoded = decryptor.decrypt(data)
     return decoded[:-decoded[-1]] # отрезаем padding с конца
    
key_longs = [170, 71, 107, 76, 96, 150, 29, 197, 242, 164, 75, 84, 212, 215, 74, 190]
content = [165, 171, 188, 243, 150, 242, 158, 103, 131, 84, 239, 147, 235, 81, 135, 61, 70, 0, 173, 155, 78, 246, 203, 0, 14, 68, 137, 156, 179, 226, 166, 27, 99, 119, 143, 53, 230, 39, 206, 104, 108, 113, 103, 230, 213, 163, 243, 243, 78, 91, 4, 204, 98, 175, 46, 215, 198, 129, 98, 94, 30, 124, 102, 114, 133, 168, 215, 112, 86, 255, 233, 22, 120, 81, 106, 90, 218, 192, 134, 153, 169, 223, 178, 193, 208, 41, 188, 108, 190, 146, 84, 53, 63, 94, 40, 18]

decrypted = aes_decrypt(bytes(key_longs), bytes(content))

print(list(decrypted))
→ Ссылка