After having generated pre-shared secret keys for IPsec VPNs, as recommended by the NSA, I wondered how “secure” the keys themselves actually were. The NSA specifically mentions the use of “large, high entropy, pre-shared keys”. Quite some time ago I wrote two posts about passwords, passphrases and a very crude and naive, home brewn, exhaustive search algorithm a.k.a. brute force tool. Now, digging a little further, but this time more into the topic of password strength, I came across appendix A of NIST SP-800-63-2. From my earlier searches I remembered this page, which lines up nicely with SP-800-63 appendix A.1, and the math behind it is not that difficult (yay!) As it turns out, this all here is pretty much on Wikipedia’s page on password strength, but this post is my 2 cents on this subject, including an offline random key generator that runs in your web browser. To calculate the strength of a password as ‘entropy’, all that is needed is:
- The length of the generated passwords’ characters (l)
- The length of the character pools’ unique characters, or alphabet (b)
Entropy (H) is calculated as:
H = log2 (b^l)
This can be rewritten as:
H = l * log2(b)
…Which then is:
H = l * ( log(b) / log(2) )
According to theory, the resulting entropy (H) is the average number of binary digits required per letter of the original language. And since bits are either 0 or 1, H bits means 2^H possible combinations.
Since calculating the entropy is fairly constant, NIST SP 800-63-2 has done some of the calculations in table A-1. And although this is said to be “at best a very crude estimate”, I’ve used it to verify the calculated entropy of a random password by the generator and seems to work pretty much ok, but without the calculation of bonuses as part of entropy estimate guessing. This would probably mean that the entropy calculated as I’ve done in the generator is the best achievable for the given pool of characters to choose from. Since the entropy is a general statistical value for all the passwords generated for this particular length and alphabet, it isn’t of much use to compare different generated passwords that were generated with the same length and alphabet. Instead, to compare the strength of the generated passwords, I estimated the time needed to brute force a generated password based on the number of its unique characters. For example, if you would have a password of 3 characters, then the password AAA would be guessable in 1 guess; as there’s no point in shuffling one and the same A around, AAB in 3, ABC in 6. So, the more unique characters were used, the higher the entropy of that particular generated password would be, since the alphabet used was slightly larger than others. More unique characters, more combinations that the attacker needs to check. That assumes that the attacker knows quite a lot: how long the password is *and* also knowns exactly which characters were used in it. I’ve added a ‘threshold’ value which acts as a minimum requirement for the number of unique characters in a generated password. Here are some presets:
|Characters used||Password length||Guesses per second||Url|
|4 digit pin-code||4||100||
|Or, really strong|
From a more practical point; This is what I would use if I needed a pre-shared key for a VPN; short enough to write down and nearly impossible to memorize for the average human being:
If you’d like some more hands-on experience cracking passwords, I can highly recommend Kali, containing all tools needed including the ultimate and awesome nmap and Metasploitable. Be sure to build an isolated hack-lab first!