This exercise gives you practice at generating pseudorandom numbers securely using the facilities offered by the standard libraries of Python and Java. If you are doing this on your own PC, there is nothing else to install, beyond having working installations of Python 3 and the JDK.
Note: the first of the tasks below can be done in Linux, WSL 2 or macOS, but not in a native Windows environment.
Open a terminal window and run the Python REPL. Then try this:
>>> f = open("/dev/urandom", "rb")
>>> f.read(16).hex()
The first of these lines opens the file-like object /dev/urandom
for
reading of binary data. Unix-inspired operating systems like Linux and
macOS expose a range of services to users through interfaces based in the
filesystem. /dev/urandom
is the particular filesystem interface from
which we can can obtain cryptographically strong pseudorandom numbers
generated by the OS1.
The second line reads 16 bytes from the opened file, then returns these bytes as a printable string of hex digits. Try repeating this line a few times to satisfy yourself that a different, seemingly random sequence of bytes is produced each time.
In a Python REPL, use the secrets
module to achieve the same result
as the previous task:
>>> import secrets
>>> secrets.token_hex(16)
This is simpler than the previous approach and also has the benefit of being
cross-platform2. Again, try repeating the call to the token_hex()
function a few times to satisfy yourself that the output changes randomly.
In the same Python REPL that was used for the previous task, try this:
>>> secrets.token_urlsafe(16)
The token_urlsafe()
function is similar to token_hex()
but it uses
Base64 encoding for the random bytes instead of hexadecimal.
This scheme produces a shorter output string, averaging 1.3 characters per
byte instead of 2 – making it more convenient for use in web applications
where you need to generate a random URL.
Look at the Recipes and Best Practices section of the API
documentation for secrets
. This gives three examples of using the module
to generate random passwords. Implement one of these examples as a Python
program and test it.
random
module for
anything security-related!
In your favourite editor or IDE, write a Java program that generates 16
random bytes (suitable for use as a key or IV in AES, for example) and then
writes these bytes to a binary file. Use the SecureRandom
class from
the java.security
package for this – see the API documentation
for further details. For a simple way of writing the bytes out to a file,
see the exercise on Symmetric Ciphers in Java.
Compile and run your program, then examine the contents of the file.
Note that most text editors can’t be used to view binary files like this in a helpful way, but if you use VSCode then you could install the Hex Editor extension to do this. On Linux or macOS you could also use the xxd tool from the command line to do a hex dump of the file. If all else fails, you could upload the file to an online hex viewer.
Run the program and examine its output a few more times to satisfy yourself that the output changes in a random fashion.
Random
class from the java.util
package for anything security-related!
□
In fact, there are two such interfaces: /dev/random
and
/dev/urandom
. The differences between these are subtle and often
misunderstood, thanks to misleading and outdated documentation. ↩︎
On Windows, it will use the BCryptGenRandom
system call of that OS,
rather than accessing /dev/urandom
. ↩︎