Toutes nos publications

Breaking Python's PRNG with a few values and no bruteforce

Python’s random module utilizes the Mersenne Twister PRNG, specifically MT19937. It’s a well-known fact that this PRNG is not cryptographically secure, as with access to 624 outputs from this PRNG it becomes possible to predict subsequent outputs. On the same subject, Ambionics Security demonstrated that it is possible to recover the Mersenne Twister seed knowing only two outputs of PHP’s mt_rand() function, without any bruteforce.

In this post, our focus will be on Python’s random implementation, drawing comparisons to PHP’s approach. We’ll cover the similarities and differences, particularly in how seeding is performed. Furthermore, we’ll demonstrate that even with a small number of outputs (as few as 6 for a 32-bit seed, akin to PHP), it’s feasible to deduce Python’s original seed.

Initialization vector mishandling

To encrypt data, one needs to choose a suitable encryption algorithm and generate a key, but most of the time additional parameters are required. In this blog post, we will focus on the initialization vector (IV), which is a parameter used by the most common symmetric encryption algorithms (AES-CBC, AES-CTR and AES-GCM). The majority of vulnerabilities I encounter during cryptographic reviews come from mishandling of this IV.

In this post we will look at what an IV is, why it is important and how to handle it safely depending on the chosen algorithm.