TypeError: Object type <class 'str'> cannot be passed to C code using pycryptodome
TypeError: Object type <class 'str'> cannot be passed to C code using pycryptodome
我有这段代码,它曾经在 Python 3.6 或 3.7 中工作(我不记得是哪个版本)
现在我在 Python 3.9.1 中尝试使用相同的代码,但出现错误。我正在使用 pycryptodome
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
SOME_SECRET_KEY = 'HPo7OLqB4Fkk4E2yGOtwqw8H5fHR9kNx67OR4g4UdlA='
SOME_IV = 'p5ldmBPdd/9pjC0bDC/nSg=='
secret_key_in_bytes = bytes(b64decode(SOME_SECRET_KEY))
iv_in_bytes = bytes(b64decode(SOME_IV))
def decrypt_with_padding(data):
cypto_obj = AES.new(secret_key_in_bytes, AES.MODE_CBC, iv_in_bytes)
decrypted = cypto_obj.decrypt(b64decode(data))
bytes_to_string = decrypted.decode("utf-8")
decrypted_data = pkcs5_unpad(bytes_to_string)
return decrypted_data
def encrypt_with_padding(data):
cypto_obj = AES.new(secret_key_in_bytes, AES.MODE_CBC, iv_in_bytes)
encrypted_data = cypto_obj.encrypt(pkcs5_pad(str(data)))
return b64encode(encrypted_data).decode()
def pkcs5_pad(s, BLOCK_SIZE=16):
return s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(
BLOCK_SIZE - len(s) % BLOCK_SIZE
)
def pkcs5_unpad(s):
return s[0: -ord(s[-1])]
if __name__ == "__main__":
data = '{"idServicio":79, "idProducto":209 , "referencia": "40425475190118187271", "montoPago": 9999, "telefono":"1111111111", "horaLocal":"20200401222821"}'
encrypted = encrypt_with_padding(data)
print(encrypted)
decrypted = decrypt_with_padding(encrypted)
print(decrypted)
这是错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-d94343c778d2> in <module>
33 if __name__ == "__main__":
34 data = '{"idServicio":79, "idProducto":209 , "referencia": "40425475190118187271", "montoPago": 9999, "telefono":"1111111111", "horaLocal":"20200401222821"}'
---> 35 encrypted = encrypt_with_padding(data)
36 print(encrypted)
37 decrypted = decrypt_with_padding(encrypted)
<ipython-input-3-d94343c778d2> in encrypt_with_padding(data)
17 def encrypt_with_padding(data):
18 cypto_obj = AES.new(secret_key_in_bytes, AES.MODE_CBC, iv_in_bytes)
---> 19 encrypted_data = cypto_obj.encrypt(pkcs5_pad(str(data)))
20 return b64encode(encrypted_data).decode()
21
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/Crypto/Cipher/_mode_cbc.py in encrypt(self, plaintext, output)
176
177 result = raw_cbc_lib.CBC_encrypt(self._state.get(),
--> 178 c_uint8_ptr(plaintext),
179 c_uint8_ptr(ciphertext),
180 c_size_t(len(plaintext)))
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/Crypto/Util/_raw_api.py in c_uint8_ptr(data)
136 return data
137 else:
--> 138 raise TypeError("Object type %s cannot be passed to C code" % type(data))
139
140 class VoidPointer_cffi(_VoidPointer):
TypeError: Object type <class 'str'> cannot be passed to C code
我尝试使用数据变量的前缀 b'string' 将字符串转换为字节,但它都不起作用。
感谢您的宝贵时间
将str转换为byte的方法是使用.encode('utf-8')。
cypto_obj.encrypt接收一个字节对象,所以需要对pkcs5_pad的输出进行编码:
def pkcs5_pad(s, BLOCK_SIZE=16):
return (s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(
BLOCK_SIZE - len(s) % BLOCK_SIZE
)).encode('utf-8')
我有这段代码,它曾经在 Python 3.6 或 3.7 中工作(我不记得是哪个版本)
现在我在 Python 3.9.1 中尝试使用相同的代码,但出现错误。我正在使用 pycryptodome
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
SOME_SECRET_KEY = 'HPo7OLqB4Fkk4E2yGOtwqw8H5fHR9kNx67OR4g4UdlA='
SOME_IV = 'p5ldmBPdd/9pjC0bDC/nSg=='
secret_key_in_bytes = bytes(b64decode(SOME_SECRET_KEY))
iv_in_bytes = bytes(b64decode(SOME_IV))
def decrypt_with_padding(data):
cypto_obj = AES.new(secret_key_in_bytes, AES.MODE_CBC, iv_in_bytes)
decrypted = cypto_obj.decrypt(b64decode(data))
bytes_to_string = decrypted.decode("utf-8")
decrypted_data = pkcs5_unpad(bytes_to_string)
return decrypted_data
def encrypt_with_padding(data):
cypto_obj = AES.new(secret_key_in_bytes, AES.MODE_CBC, iv_in_bytes)
encrypted_data = cypto_obj.encrypt(pkcs5_pad(str(data)))
return b64encode(encrypted_data).decode()
def pkcs5_pad(s, BLOCK_SIZE=16):
return s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(
BLOCK_SIZE - len(s) % BLOCK_SIZE
)
def pkcs5_unpad(s):
return s[0: -ord(s[-1])]
if __name__ == "__main__":
data = '{"idServicio":79, "idProducto":209 , "referencia": "40425475190118187271", "montoPago": 9999, "telefono":"1111111111", "horaLocal":"20200401222821"}'
encrypted = encrypt_with_padding(data)
print(encrypted)
decrypted = decrypt_with_padding(encrypted)
print(decrypted)
这是错误
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-d94343c778d2> in <module>
33 if __name__ == "__main__":
34 data = '{"idServicio":79, "idProducto":209 , "referencia": "40425475190118187271", "montoPago": 9999, "telefono":"1111111111", "horaLocal":"20200401222821"}'
---> 35 encrypted = encrypt_with_padding(data)
36 print(encrypted)
37 decrypted = decrypt_with_padding(encrypted)
<ipython-input-3-d94343c778d2> in encrypt_with_padding(data)
17 def encrypt_with_padding(data):
18 cypto_obj = AES.new(secret_key_in_bytes, AES.MODE_CBC, iv_in_bytes)
---> 19 encrypted_data = cypto_obj.encrypt(pkcs5_pad(str(data)))
20 return b64encode(encrypted_data).decode()
21
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/Crypto/Cipher/_mode_cbc.py in encrypt(self, plaintext, output)
176
177 result = raw_cbc_lib.CBC_encrypt(self._state.get(),
--> 178 c_uint8_ptr(plaintext),
179 c_uint8_ptr(ciphertext),
180 c_size_t(len(plaintext)))
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/Crypto/Util/_raw_api.py in c_uint8_ptr(data)
136 return data
137 else:
--> 138 raise TypeError("Object type %s cannot be passed to C code" % type(data))
139
140 class VoidPointer_cffi(_VoidPointer):
TypeError: Object type <class 'str'> cannot be passed to C code
我尝试使用数据变量的前缀 b'string' 将字符串转换为字节,但它都不起作用。
感谢您的宝贵时间
将str转换为byte的方法是使用.encode('utf-8')。 cypto_obj.encrypt接收一个字节对象,所以需要对pkcs5_pad的输出进行编码:
def pkcs5_pad(s, BLOCK_SIZE=16):
return (s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(
BLOCK_SIZE - len(s) % BLOCK_SIZE
)).encode('utf-8')