Symmetric Encryption
73
Salt
By adding a random piece of data to the password before hashing it, we greatly increase the number of
possible keys created from a single password. Without a salt, the word "sasquatch" hashes to a specific
value. If we add 8 bytes of random data before hashing it, then "sasquatch" can hash to 264 possible values.
That means that it is effectively impossible to create a precompiled-key list dictionary, as it would be far too
large. Instead, the attacker is forced to perform a hashing computation rather than a simple lookup on the
data, which will take quite some time.
The salt is stored with the data that is encrypted. Each time a new piece of data is encrypted, a new salt is
generated. This means that the same phrase will encrypt to a different value each time it is encrypted, even
if the same password is used every time. To decrypt, the salt must be extracted from the encrypted data,
and then combined with the password to create the decryption key.
An example of the use of a salt is the password checking system in Linux. Typically passwords are MD5-
hashed with a random salt. The salt is then prepended to the resulting hash. That salt and hash are then
written to the password file. The first few characters are the salt and the remaining characters are the
password hashed with the salt. When someone tries to log in, the operating system reads the password they
type in and their entry in the password file. It then hashes the user's typing along with the first characters of
their password entry. If the resulting hash is equal to the remaining characters in their entry, their password
is correct.
In just a moment we'll show an example of using salt and password-based encryption that should help make
this process clearer.
Iteration Count
The iteration count is an attempt to increase the time that an attacker will have to spend to test possible
passwords. If we have an iteration count of a thousand, we need to hash the password a thousand times,
which is a thousand times more computationally expensive than doing it just once. So now our attacker will
have to spend 1000 times more computational resources to crack our password-based encryption.
Password-Based Encryption Example
Let's write a simple class that does password-based encryption and decryption. We'll use an iteration count
of 1000, and a random 8-byte or 64-bit salt. When we write the ciphertext out, the first 64 bits will be the
salt that we need to use to create the key to decrypt it. When we decrypt, we'll use those 64 bits as the salt
and we'll only decrypt the ciphertext that begins after the 64th bit. Note that the salt isn't being kept secret
it's just different for each batch of text that we're going to encrypt.
We want the output of the example to be displayable on the screen. To accomplish that, we're going to
BASE 64 encode the output, which transforms binary data into ASCII characters.
BASE64 Encoding
Binary data is typically stored in bytes of 8-bits. Standard ASCII is only 7 bits though, so if we want to
display binary as ASCII, we're going to lose at least one bit per byte. BASE64 encoding is a way of
overcoming this problem. 8-bit bytes are converted to 6-bit chunks and then into characters. Six bits are
used so that some control characters can be used indicating when the data ends. The encoded characters
can then be displayed on the screen and converted back into binary with no difficulty. Of course, since
we're moving from an 8-bit chunk to a 6-bit chunk, we're going to have more chunks 3 bytes becomes 4
characters and vice-versa.