Crypto.AES 報錯 | TypeError: Object type cannot be passed to C code


一、加密代碼

import base64
import zlib
from Crypto.Cipher import AES
from Crypto import Random


BLOCK_SIZE = 16


def pad(s): return s + ((BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)).encode("utf-8")


class AESCipher:
    def __init__(self, key):

        self.key = key

    def encrypt(self, raw):

        """
        加密
        """

        raw = pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return iv + cipher.encrypt(raw)


def encode(data, key) -> bytes:

    """
    :param data: 序列化后的數據
    :param key: 加密的 key
    :return: 
    """

    # 壓縮
    compress_data = zlib.compress(data)

    # 加密
    aes = AESCipher(key)
    encrypt_data = aes.encrypt(compress_data)

    # 轉成Base64編碼
    encode_data = base64.b64encode(encrypt_data)
    return encode_data


if __name__ == '__main__':
    key = hashlib.md5(str(time.time()).encode('utf-8')).hexdigest()
    json_data = json.dumps({'data': 'test'})
    encode_data = encode(json_data, key)
View Code

 

二·、報錯相關

1、報錯信息
    cipher = AES.new(self.key, AES.MODE_CBC, iv)
  File "D:\Python37\Lib\Crypto\Cipher\AES.py", line 232, in new
    return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
  File "D:\Python37\Lib\Crypto\Cipher\__init__.py", line 79, in _create_cipher
    return modes[mode](factory, **kwargs)
  File "D:\Python37\Lib\Crypto\Cipher\_mode_cbc.py", line 274, in _create_cbc_cipher
    cipher_state = factory._create_base_cipher(kwargs)
  File "D:\Python37\Lib\Crypto\Cipher\AES.py", line 103, in _create_base_cipher
    result = start_operation(c_uint8_ptr(key),
  File "D:\Python37\Lib\Crypto\Util\_raw_api.py", line 144, in c_uint8_ptr
    raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type <class 'str'> cannot be passed to C code


2、報錯代碼
cipher = AES.new(self.key, AES.MODE_CBC, iv)
View Code

 

三、報錯原因

  AES.new 方法的第一個參數,需要為 bytes/bytearray/memoryview 類型,報錯代碼中傳遞的是 字符串 類型,將其轉為 bytes 類型即可

 

四、修改之后

import base64
import zlib
from Crypto.Cipher import AES
from Crypto import Random


BLOCK_SIZE = 16


def pad(s): return s + ((BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)).encode("utf-8")


class AESCipher:
    def __init__(self, key):

        self.key = key

    def encrypt(self, raw):

        """
        加密
        """

        raw = pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key.encode(), AES.MODE_CBC, iv)       ### 我在這里
        return iv + cipher.encrypt(raw)


def encode(data, key) -> bytes:

    """
    :param data: 序列化后的數據
    :param key: 加密的 key
    :return: 
    """

    # 壓縮
    compress_data = zlib.compress(data)

    # 加密
    aes = AESCipher(key)
    encrypt_data = aes.encrypt(compress_data)

    # 轉成Base64編碼
    encode_data = base64.b64encode(encrypt_data)
    return encode_data


if __name__ == '__main__':
    key = hashlib.md5(str(time.time()).encode('utf-8')).hexdigest()
    json_data = json.dumps({'data': 'test'})
    encode_data = encode(json_data, key)
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM