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.