Расшифровка иглобрюха

#python-3.x #python-2.7 #encryption #blowfish

Вопрос:

Я смотрю на довольно старый код Python 2, в котором они извлекают данные из файла .wotreplay, что я и хочу сделать.

Чтобы расшифровать файл воспроизведения, они используют этот код:

 def decrypt_file(fn, offset=0):
    key = ''.join(['xDE', 'x72', 'xBE', 'xA0', 'xDE', 'x04', 'xBE', 'xB1', 'xDE', 'xFE', 'xBE', 'xEF', 'xDE', 'xAD', 'xBE', 'xEF'])
    bc = 0
    pb = None
    from blowfish import Blowfish
    from binascii import b2a_hex
    bf = Blowfish(key)
    printmessage("Decrypting from offset {}".format(offset))
    of = fn   ".tmp"
    with open(fn, 'rb') as f:

        f.seek(offset)
        with open(of, 'wb') as out:
            while True:
                b = f.read(8)
                if not b:
                    break
    
                if len(b) < 8:
                    b  = 'x00' * (8 - len(b))  # pad for correct blocksize
    
                if bc > 0:
                    db = bf.decrypt(b)
                    if pb:
                        db = ''.join([chr(int(b2a_hex(a), 16) ^ int(b2a_hex(b), 16)) for a, b in zip(db, pb)])
    
                    pb = db
                    out.write(db)
                bc  = 1
            return of
    return None
 

С помощью этого метода расшифровки blowfish, однако это код Python 2.

Я пытаюсь сделать что-то подобное с этим пакетом

Повтор можно скачать здесь (я не смог загрузить его в этом посте, ссылка является прямой загрузкой)

 from binascii import b2a_hex
from blowfish import Cipher


start_pointer = 8
filename = 'replay.wotreplay'


def _decrypt_file(self, offset: int = 0) -> str:
    block_count = 0
    pb = None
    cipher = Cipher(bytes(''.join(['xDE', 'x72', 'xBE', 'xA0', 'xDE', 'x04', 'xBE', 'xB1', 'xDE', 'xFE', 'xBE', 'xEF', 'xDE', 'xAD', 'xBE', 'xEF']), encoding='utf-8'))

    temp_file = filename   '.tmp'
    with open(filename, 'rb') as in_file:
        in_file.seek(offset)

        with open(temp_file, 'wb') as out_file:
            while True:
                block = in_file.read(8)
                if not block:
                    break

                if len(block) < 8:
                    block  = 'x00' * (8 - len(block))

                if block_count > 0:
                    db = cipher.decrypt_block(block)
                    if pb:
                        db = ''.join([
                            chr(int(b2a_hex(bytes(a)), 16) ^ int(b2a_hex(bytes(block)), 16))
                            for a, block in zip(db, pb)
                        ])

                    pb = db
                    out_file.write(db)

                block_count  = 1

            return temp_file
 

However I can’t seem to figure out how to make this work, as I constantly get errors like this

 Traceback (most recent call last):
  File "..extract.py", line 196, in <module>
    extractor.extract()
  File "..extract.py", line 184, in extract
    destination_file = self._decrypt_file(self._start_pointer)
  File "..extract.py", line 119, in _decrypt_file
    db = ''.join([
  File "..extract.py", line 120, in <listcomp>
    chr(int(b2a_hex(bytes(a)), 16) ^ int(b2a_hex(bytes(block)), 16))
TypeError: string argument without an encoding
 

How am I supposed to do this? Should I use Crypto.Cipher.Blowfish instead?