3

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?

7
  • That’s not telling you the length of the object... Commented May 5, 2018 at 14:50
  • getsizeof doesn't give you the exact size of the value that your object holds it returns the size of the whole object include all the attributes, namespace, etc. Commented May 5, 2018 at 14:52
  • What should I use instead? If I use rnd_bytes for crypto functions that expect 16 bytes long input, I receive an error: "ValueError: Value must be 16 bytes long" Commented May 5, 2018 at 14:52
  • 1
    Then could you give a minimal reproducible example of that? Commented May 5, 2018 at 14:53
  • Use len instead. Commented May 5, 2018 at 15:06

1 Answer 1

12

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.