Score:2

How less secure were those random bytes?

kn flag

In our Python codebase, some random bytes were generated that we wanted to be cryptographically secure. Previously, the code was:

capability = "".join(secrets.choice(string.digits) for i in range(33))

I've changed it to:

capability = secrets.token_bytes(16)

By my estimation, the first version chose 33 times between 10 digits and so had 33*log2(10)=110bits of entropy, while the second has 128bits of entropy. Is this calculation correct?

poncho avatar
my flag
"How less secure were those random bytes"; it also depends on what you did with those bytes. For example, if you used them as an AES-128 key, well, that means that you most likely used only the first 16 bytes of the first example, which is *significantly* worse than "110 bits security"
Maarten Bodewes avatar
in flag
I agree with Poncho. I don't see anything wrong with your calculations, but it then depends on how the digits are used (and considering the method for generating them, that may be any good or bad way). Once thing is also that if this is considered a number that you might end up with a few leading zeros, which may be removed before the value is used. It again depends on the code thereafter if that has a significant impact or not.
Maarten Bodewes avatar
in flag
Beware of the Duck-typing used in Python. Having a String consisting of digits or bytes is rather different. I don't like using strings for binary values; if I'd design an API I would just accept [`bytes` or `bytearray`](https://www.w3resource.com/python/python-bytes.php) for Python 3
kn flag
We use the whole thing to make an unguessable URL (wiith base64).
Score:3
us flag

Your math are correct, theoretically. Indeed, using printable digits to store randomness is a trade-off between storage and readability. However, since you are talking about cryptographic security, I want to mention something.

When considering randomness there are two things you should keep in mind : unpredictability and uniformity.

  • Not your case but, if you are using python built-ins like random, you have uniformity but not unpredictability, because it uses a PRNG. So, speaking cryptographic wise according to Kerchoff's laws, you get 0 entropy.
  • If you are using secrets. It uses (in Linux for exmaple) /dev/urandom which is generally considered cryptographically secure *, except in some cases (e.g. while booting) you get an estimated amount of entropy (you can't actually measure it) that you hope it is a little bit less than your theoretical one.

* There is/was an ongoing debate on whether to use /dev/urandom or /dev/random. You can read more here and you can also check SAI Peregrinus' comment bellow.

Paul Uszak avatar
cn flag
Err, what do you mean _"using printable digits to store randomness is a trade-off between storage and readability"_? Are you concerned with storage capacity?
SAI Peregrinus avatar
si flag
That "ongoing debate" hasn't been a debate for some time now. Current Linux kernels have *no* difference in behavior between /dev/random and /dev/urandom. They block at boot until the pool is seeded, then don't block afterwards.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.