Reputation: 1263
I want to generate a 16 bytes long random string for encryption purpose (AES encryption) in python3. urandom(n)
seems to be the way to go to get real random characters:
os.urandom(n):
Return a string of n random bytes suitable for cryptographic use.
As I need a 16 bytes random string, I thought this would do the job for me: EDIT I included now a more complex example, demonstrating the issues I have.
from os import urandom
from Crypto.Cipher import AES
from base64 import b64encode
import sys
rnd=urandom(16)
rnd_bytes=b64encode(rnd).decode('utf-8')
print(sys.getsizeof(rnd_bytes))
print(len(rnd_bytes))
print(type(rnd_bytes))
AESencrypter=AES.new('my key',AES.MODE_CBC,rnd_bytes)
Note: I used this answer for converting the urandom byte to a string. The output is:
73
24
File "/User/test.py", line 14, in AESencrypter=AES.new('my kes',AES.MODE_CBC,rnd_bytes) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 95, in new return AESCipher(key, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 59, in init blockalgo.BlockAlgo.init(self, _AES, key, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/Crypto/Cipher/blockalgo.py", line 141, in init self._cipher = factory.new(key, *args, **kwargs) ValueError: IV must be 16 bytes long
As you see, the length is not 16 (probably because of the conversion between byte and string). How can I fix that?
Upvotes: 3
Views: 13316
Reputation: 16951
What you get back from urandom()
is the length you asked for:
>>> rnd = os.urandom(16)
>>> rnd
b'\xf0\xe9ZG3\xf0(\xd2\xc3\x04/\xf1\xae\x0b-\xb4'
>>> len(rnd)
16
So use that as is.
If you encode it in base-64 it won't be 16 bytes anymore. That is because base-64 (1) pads out your data to a multiple of 3 bytes, making it 18 long, and then (2) encodes each group of 3 bytes as 4 bytes (so that they will all be printable characters), which makes it longer still. That explains the length of 24 that you report.
Do not use sys.getsizeof()
to discover the length of your data. That returns the size of Python's internal data structure.
Upvotes: 12