Implementing-cryptography-using-python
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
144 Chapter 5 ■ Stream Ciphers and Block Ciphers
mental during World War II, are the encryption version of a salt and save us
from the inherent risks of a user sending the same message several times. You
have explored how to fix one flaw of the one-time pad by generating a key that
is the same length as the message; you still cannot use the same key multiple
times. Two possible fixes could include the following:
■■
Do not restart the PRNG: Not restarting the PRNG requires both sides
to carefully coordinate with each other so that they stay at the same part
of the communication stream on the encryption and decryption side; this
could offer challenges if some messages are lost in transit or if there are
parallel message-sending channels.
■■
Use some public randomness to change the secret key effectively: This
idea is that you generate, from a true entropy source, a nonce. A nonce is
a one-time set of random bytes that mingles with the private key to change
the output of the encryption scheme.
The ultimate goal of this is to allow you to send the same message 100 times
in a row, with the same private key, and each time it would look entirely random
and uncorrelated. From here on out, your goal is to use a nonce/IV so that the
same message is never encrypted the same way twice. Most computers have a
source of randomized bytes from entropy that we can pull data from to build
random bytes. They pool sources of entropy like temperature, user actions, timings,
and other unique factors. This information is then used by CSPRNGs to
turn that entropy into uniform random bytes. A poorly generated key or initial
seed will cripple even the most secure CSPRNG.
In the previous encryption scheme, you created a PRNG function along with a
secret seed. Now we begin by generating a nonce so that when you are encrypting
a message, you first generate some entropy bytes that pass along with the
ciphertext. The nonce should be sent in the clear, so it should look random. To
generate six bytes of noise, use the following Python code:
import os
nonce = os.urandom(6)
print(nonce)
Ideally, you need a convention to translate the nonce and your secret key
(54321) into a new seed or key. Other schemes may have their ways of letting
the nonce interact with the scheme; in this case, changing the seed is excellent
for learning the concepts. The method presented here will be to concatenate
the nonce and the secret key (as hex), then to apply the SHA256 hash function
to those bytes (not hex), and take the lowest 32 bits as the new seed.
Here is what the Python looks like:
import os, hashlib, binascii
nonce = os.urandom(6)