Тип объекта <class 'tuple'> не может быть передан в код на C при шифровании файла в django

Итак, я хочу зашифровать файл .txt ключевым словом, которое я ввел. но я получил сообщение об ошибке

Тип объекта <class 'tuple'> не может быть передан в код C

Моя проблема заключается в следующем коде:

aes = AES.new(key.encode('utf8'), AES.MODE_CTR, counter=ctr)

если я добавляю encode в ctr, то получаю сообщение об ошибке у объекта 'dict' нет атрибута 'encode'

если я не добавляю никакой кодировки к key и ctr, то получаю сообщение об ошибке Object type <class 'str'> cannot be passed to C code

может кто-нибудь помочь мне исправить это? я использовал django для шифрования с AES 128 с методом CTR. или может кто-нибудь может дать мне пример шифрования AES с другим методом, но может быть запущен в django. вот мой полный код функции:

# AES supports multiple key sizes: 16 (AES128), 24 (AES192), or 32 (AES256).
key_bytes = 16
# Takes as input a 32-byte key and an arbitrary-length plaintext and returns a
# pair (iv, ciphtertext). "iv" stands for initialization vector.
def encrypt(key, testpass):
    assert len(key) == key_bytes
    print(testpass)
    print(key)
    # Choose a random, 16-byte IV.
    iv = Random.new().read(AES.block_size)

    # Convert the IV to a Python integer.
    iv_int = int(binascii.hexlify(iv), 16)

    # Create a new Counter object with IV = iv_int.
    ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
    print(ctr)

    # Create AES-CTR cipher.
    aes = AES.new(key.encode('utf8'), AES.MODE_CTR, counter=ctr)

    # Encrypt and return IV and ciphertext.
    ciphertext = aes.encrypt(testpass)
    print(iv)
    print(ciphertext)
    return (iv, ciphertext)

Ваши тестовые данные - это ('testpass_3kEMV2T.txt',), вам нужно извлечь элемент из tuple и передать его как bytes в метод encrypt, потому что метод AES.encrypt требует bytes | bytearray | memoryview в качестве аргумента. Вот версия вашего encrypt, которая определяет, является ли передаваемый вами аргумент str и кодирует его в байты, если это так (но она не проверяет, является ли он иначе bytes, я оставляю это как упражнение для вас, если вы хотите более строгой проверки).

import binascii


from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto import Random

key_bytes = 16

# here's a rudimentary change that accepts bytes or
# str
def encrypt(key, plaintext):
    if isinstance(plaintext, str):
        plaintext = plaintext.encode("utf-8")

    assert len(key) == key_bytes
    # Choose a random, 16-byte IV.
    iv = Random.new().read(AES.block_size)

    # Convert the IV to a Python integer.
    iv_int = int(binascii.hexlify(iv), 16)

    # Create a new Counter object with IV = iv_int.
    ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
    print(ctr)

    # Create AES-CTR cipher.
    aes = AES.new(key.encode('utf8'), AES.MODE_CTR, counter=ctr)

    # Encrypt and return IV and ciphertext.
    ciphertext = aes.encrypt(plaintext)
    return (iv, ciphertext)

# for now, since you're getting your data from the db which is a 1-tuple, you have to pull out the first elem
testpass = ('testpass_3kEMV2T.txt',)
print(encrypt("a"*16, testpass[0]))

Выход:

{'counter_len': 16, 'prefix': b'', 'suffix': b'', 'initial_value': 302861312392273214314458272471454024973, 'little_endian': False}
(b'\xe3\xd8\xf7\x90\xcd\x96m\xcb\xa5g)\xd1\xda\xc3\x85\r', b'-F)\x83\x9a\xf9\xe1\xc3\xfb\xfa_<^\x1c:q\x07\xa1@\xbb')
Вернуться на верх