【问题标题】:PyCryptoDome Version 3.6.6 raises an TypeError: Object type <class 'str'> cannot be passed to C codePyCryptoDome 版本 3.6.6 引发类型错误:对象类型 <class 'str'> 无法传递给 C 代码
【发布时间】:2018-08-20 07:50:44
【问题描述】:

几年前,我使用 PyCryptoDome 版本 2.6.1 在 python 中创建了一个密码模块。

现在有了新的 PyCryptoDome 版本 3.6.6 和 Python 3.6,我得到了一个具有相同代码的 TypeError。错误在“_init_crypter”中抛出 - 方法:

  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/AES.py", line 206, in new
    return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/__init__.py", line 79, in _create_cipher
    return modes[mode](factory, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/_mode_cbc.py", line 253, in _create_cbc_cipher
    return CbcMode(cipher_state, iv)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/_mode_cbc.py", line 96, in __init__
    c_uint8_ptr(iv),
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Util/_raw_api.py", line 196, 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

我该如何解决这个问题!

我的两个版本的代码:

import os
from base64 import b64encode, b64decode
import hashlib
from Crypto.Cipher import Blowfish, AES


class Crypt:

    fileextension = ".enc"

    def __init__(self, crypter, key="", encoding="utf-8"):
        self._mode = -1
        self._encoding = encoding
        self._crypter = Blowfish
        self._blocksize = 8
        self._key_32byte = ""
        self._cryptographer = None

        self.set_crypter(crypter)
        if key:
            self.set_key(key)

    def _init_crypter(self):

        # self._key_32byte          <- set in set_key-method
        # self._mode = AES.MODE_CBC <- set in set_crypter-method
        # self._blocksize = 16      <- set in set_crypter-method

        self._cryptographer = self._crypter.new(
            self._key_32byte,
            self._mode,
            IV=self._blocksize * '\x00'
        )

    # and further code ...

【问题讨论】:

    标签: python pycryptodome


    【解决方案1】:

    密钥和IV 参数必须是二进制类型(bytes)而不是文本类型(str)。

    如果您从文件中加载密钥,请务必以二进制模式打开它:

    with open('keyfile', 'rb') as f:
        ...
    

    如果您的密钥是代码中的文字,请确保它是二进制文字:

    key = b'badbadbadkey'
    

    最后,要构造IV 参数,它必须是bytes 的序列。

    例如:

    >>> Blowfish.new(b'badbadbadkey', 2, IV=8 * b'\x00')
    <Crypto.Cipher._mode_cbc.CbcMode object at 0x7f434187b8d0>
    

    【讨论】:

    • 我刚刚写了我的解决方案 - 丢失的 b ;)。但是非常感谢@Anthony Sottile
    • 如果这个答案对您有帮助,请考虑接受并点赞!
    【解决方案2】:

    好的 - 几个小时后我明白了!只有一封信解决了这个问题: '\x00' 必须是 b'\x00':

    def _init_crypter(self):
        self._cryptographer = self._crypter.new(
            self._key_32byte,
            self._mode,
            IV=self._blocksize * b'\x00'
        )
    

    【讨论】:

      猜你喜欢
      • 2021-09-08
      • 1970-01-01
      • 2018-10-22
      • 2022-01-07
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      相关资源
      最近更新 更多