Cryptographic hashing functions are used to create digital signatures, message authentication codes (MACs) and other forms of authentication. They are also used to store user passwords in databases instead of storing the password in clear text and help prevent data leakage in session management for web applications. The actual algorithm used to create a cryptology function varies per implementation (MD5, SHA-512, etc.) but the main function is to take arbitrary block of data and return a fixed-size bit string.
The code reviewer needs to be aware of three main things when reviewing code that uses cryptographic hashing functions.
- Legality of the cryptographic hashing functions if the source code is being exported to another country.
- The life cycle of the cryptographic hashing function being used.
- Basic programming of cryptographic hashing functions.
In the United States in 2000, the department of Commerce Bureau of Export revised encryption export regulations. The results of the new export regulations it that the regulations have been greatly relaxed. However if the code is to be exported outside of the source country current export laws for the export and import counties should be reviewed for compliance.
Case in point is if the entire message is hashed instead of a digital signature of the of message the National Security Agency (NSA) considers this a quasi-encryption and State controls would apply.
It is always a valid choice to seek legal advice within the organization that the code review is being done to ensure legal compliance.
With security nothing is secure forever. This is especially true with cryptographic hashing functions. Some hashing algorithms such as Windows LanMan hashes are considered completely broken. Others like MD5, while currently considered safe for password hash usage, have known issues like collision attacks (note that collision attacks do not affect password hashes). The code reviewer needs to understand the weaknesses of obsolete hashing functions as well as the current best practices for the choice of cryptographic algorithms.
The most common programmatic issue with hashing is not using a salt value or if using a salt the salt value is too short and or the same salt value is used in multiple hashes. The purpose of a salt is to make it harder for an attacker to perform pre-computed hashing attack (e.g., using rainbow tables) but other benefits of a salt can include making it difficult for an attacker to perform even password guessing attacks by obsfucating the hashed value.
One way to generate a secure salt value is using a pseudo-random number generator. Note that a salt value does not need to possess the quality of a cryptographically secure randomness.
- Java – java.security.SecureRandom
- Net (C#,VB) - System.Security.Cryptography.RNGCryptoServiceProvider
- PHP - ???
- Ruby - ???
- Perl - ???
- C++ none managed code on CLR or none windows ????
The salt value does not need to be secret and can be stored along with the hash value. Some may use a combination of account details (username, user full name, ID, creation date, etc.) as the salt for hash to further obsfucate the hash computation: for example salt = (username|lastname|firstname|ID|generated_salt_value).
Lastly, never accept in a code review an algorithm created by the programmer for hashing or copy a hashing function taken from the Internet. Always use cryptographic functions that are provided by the language framework the code is written in. These functions are well vetted and well tested by experience cryptographers.