 Engineering in the white spaces

Edit:This password utilities library has now been substantially upgraded and open-sourced with an MIT license. You can find a .NET 4.0 version of the library and an example graphical interface in a Google Code Mercurial repository.

This is the seventh installment in a series about creating a C# password utilities library.

The final step is to measure the information entropy of specific passwords and their hashes. In this context, entropy is a measure of unpredictability. For randomly-generated passwords, the information entropy (measured in bits) is a reasonable proxy for password strength. For example, a password with 42 bits of entropy is as strong as a string of 42 bits chosen randomly. An attacker would need 242 attempts to exhaust every possibility of finding this password by brute force. Adding an extra bit of entropy doubles the number of guesses required, making the attacker's task twice as difficult.

The standard formula for calculating the information entropy of a random password is L * ( logarithm N / logarithm 2), where L is the number of symbols in the password and N is the number of possible symbols. The result is expressed in bits. The entropy of a password hash is calculated using a similar formula, logarithm N / logarithm 2, where N is the number of hash iterations.

The EntropyChecker.cs class can measure the entropy of:

• A machine-generated password where the policy is not known.
• A password generated by a human.
• A password hash, based on the number of hash iterations.

The following code measures the entropy of a machine-generated random password where the password policy is known. In this case, the password itself isn't required. The password policy knows the allowed password symbols, and that list combined with the password length is enough to calculate the password strength. The following code measures the entropy of a machine-generated random password where the password policy is not known. In this case, the password is analysed to discover which symbols it contains. Based on that, the list of allowed symbols is estimated, and then the entropy can be measured as before. One caveat is that if the code detects a non-ASCII symbol in the password, it has no way of knowing what range of non-ASCII symbols was used to construct the password. So it assigns an arbitrary number of non-ASCII symbols, in this case 100. To deal with this, the code uses a NIST formula contained in a Wikipedia article on password strength. The result is that human passwords always show as much weaker than machine-generated random passwords. The following code measures the entropy of a password hash, based on the number of hash iterations. As an example, the default hash policy uses 214 hash iterations, which increases the password's entropy by 14 bits. According to Moore's Law, each extra bit of entropy provided by the hash means an extra 18 months to crack the password in the same time as today. So it will be 21 years (14 x 18 months) before the iterated hash can be cracked in the same time as the raw password can be cracked today. Finally the information entropy in bits is converted to an estimated password strength in 2011 terms. This conversion is really a guesstimate, and will be increasingly inaccurate as hardware scales up (CPU/GPU speed, memory speed/size) and out (grids, etc).

• In 1998, the EFF cracked a 56-bit key in 56 hours using specialised FPGA hardware.
• In 2002, distributed.net cracked a 64-bit key in 4 years, 9 months, and 23 days.
• In 2010, distributed.net estimated that cracking a 72-bit key using current hardware would take about 48,712 days or 133.5 years.
• NIST recommends 80 bits for the most secure passwords. You can view and download EntropyChecker.cs. The complete password utilities library, including this class, will be posted at the end of this series. This completes our analysis of the library itself. In the next installment, we'll look at a console program that tests all of the functions of this library.