Object type <class 'str'> cannot be passed to C code – virtual environment
Question:
I am using Mac Anaconda. And I try to use the AES of Crypto. However, I face a strange problem.
I just want to excute a simple line of code:
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
if I run the code without the virtual environment as below it is OK.
$ python
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more
information.
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
if I run with the virtual environment "testaes" then I got the error:
(testaes)$ python
Python 3.6.4 |Anaconda, Inc.| (default, Mar 12 2018, 20:05:31)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 200, in new
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/__init__.py", line 55, in _create_cipher
return modes[mode](factory, **kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/_mode_cbc.py", line 234, in _create_cbc_cipher
cipher_state = factory._create_base_cipher(kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 100, in _create_base_cipher
result = start_operation(c_uint8_ptr(key),
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Util/_raw_api.py", line 109, 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
You can see that at both time I use the the same Anaconda Python 3.6.4 and GCC4.2.1. How to solve this?
Answers:
In Python 3, encode it into a bytearray
:
obj = AES.new('This is a key123'.encode("utf8"), AES.MODE_CBC, 'This is an IV456'.encode("utf8"))
If you store these in variables and want to use them as (Python) strings again, just use:
key_as_bytearray.decode("utf8")
Check out this answer for further information.
Python has package named pycryptodome which causes this error.just uninstall the package
sudo pip3 uninstall pycryptodome
Just encode the key and you will get no error:
from Crypto.Cipher import AES
import base64
key = ''
cipher_text = ''
cipher_text = base64.b64decode(cipher_text)
decipher = AES.new(key.encode(), AES.MODE_ECB)
print(decipher.decrypt(cipher_text))
from Crypto.Cipher import AES
import base64
def encrypt(text):
private_key = "xxx".encode('utf-8')
iv = "yyy".encode('utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
encrypted = base64.b64encode( cipher.encrypt(pad(text)))
return encrypted.decode("utf-8")
This was working fine in Google Collab but It was not showing this above error in Python3 Terminal in Linux. So What I did is –
from Crypto.Cipher import AES
from base64 import b64encode
from Crypto.Util.Padding import pad, unpad
def encrypt(text):
private_key = bytes("xxx", 'utf-8')
iv = bytes("yyy", 'utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(pad(text.encode("UTF-8"), AES.block_size))
return b64encode(encrypted).decode('utf-8')
I am using Mac Anaconda. And I try to use the AES of Crypto. However, I face a strange problem.
I just want to excute a simple line of code:
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
if I run the code without the virtual environment as below it is OK.
$ python
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more
information.
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
if I run with the virtual environment "testaes" then I got the error:
(testaes)$ python
Python 3.6.4 |Anaconda, Inc.| (default, Mar 12 2018, 20:05:31)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 200, in new
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/__init__.py", line 55, in _create_cipher
return modes[mode](factory, **kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/_mode_cbc.py", line 234, in _create_cbc_cipher
cipher_state = factory._create_base_cipher(kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 100, in _create_base_cipher
result = start_operation(c_uint8_ptr(key),
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Util/_raw_api.py", line 109, 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
You can see that at both time I use the the same Anaconda Python 3.6.4 and GCC4.2.1. How to solve this?
In Python 3, encode it into a bytearray
:
obj = AES.new('This is a key123'.encode("utf8"), AES.MODE_CBC, 'This is an IV456'.encode("utf8"))
If you store these in variables and want to use them as (Python) strings again, just use:
key_as_bytearray.decode("utf8")
Check out this answer for further information.
Python has package named pycryptodome which causes this error.just uninstall the package
sudo pip3 uninstall pycryptodome
Just encode the key and you will get no error:
from Crypto.Cipher import AES
import base64
key = ''
cipher_text = ''
cipher_text = base64.b64decode(cipher_text)
decipher = AES.new(key.encode(), AES.MODE_ECB)
print(decipher.decrypt(cipher_text))
from Crypto.Cipher import AES
import base64
def encrypt(text):
private_key = "xxx".encode('utf-8')
iv = "yyy".encode('utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
encrypted = base64.b64encode( cipher.encrypt(pad(text)))
return encrypted.decode("utf-8")
This was working fine in Google Collab but It was not showing this above error in Python3 Terminal in Linux. So What I did is –
from Crypto.Cipher import AES
from base64 import b64encode
from Crypto.Util.Padding import pad, unpad
def encrypt(text):
private_key = bytes("xxx", 'utf-8')
iv = bytes("yyy", 'utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(pad(text.encode("UTF-8"), AES.block_size))
return b64encode(encrypted).decode('utf-8')