It's well understood that developers, and especially line-of-business developers, spend much more time reading and understanding existing code than writing new code. Yet one of the most common interview approaches emphasises writing new code.

So one of my standard developer interview questions is to give the candidate a few lines of rather dodgy code and ask the following:

After some reader feedback and a real-life deployment, I've re-factored the password utilities library to be more functional, easier to use, and more maintainable. This has enabled the following improvements:

The ability to define and use any combination of the default and custom character sets when generating passwords. There are six default character sets covering the normal ASCII range. You can define as many custom character sets as you wish, with the caveat that the current code allows passwords to be generated from a maximum of 255 unique characters.

The ability to encode all of the hash information needed to verify the associated password at a later stage. This includes the hash algorithm (SHA1-160, SHA2-256, SHA3-512, BCRYPT-192, or SCRYPT-512), the salt/hash encoding format (HEX or BASE64), the work factor (number of hash iterations), the encoded password salt, and the encoded password hash.
This information is returned in a printable ASCII string that can be stored in a database or other location.

An interactive Windows Forms user interface that demonstrates most of the library's capabilities.

Some usability and library interface improvements along with a couple of bug fixes.

Before demonstrating the new password utilities library, we interrupt our scheduled programming to bring you the latest offender in end-user personal data storage. Sony's Playstation Network and Qriocity services have recently suffered a major intrusion that exposed personal data for its 77 million users. It's not completely clear from their FAQs, but it appears that the user passwords weren't hashed or encrypted, but instead stored in plain text. This makes the Sony rootkit fiasco positively tame in comparison. Read more

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.

To create the salted hash, we're going to use the .NET Framework's implementation of a key derivation function called PBKDF2, also published as RFC 2898. PBKDF2 has some useful properties: you can use a salt, you can define the hash output size, and you can configure the slowdown factor by specifying the number of iterations over the hash function. Read more

Hashing a password involves a one-way function that converts an (optionally salted) password into a fixed-size set of bits. The idea is that you always store the password hashes rather than the passwords themselves. After storing a password hash, you can then verify the associated password, by hashing it and then comparing with the stored hash. Read more

Now that we have a PasswordPolicy class and a Die class, the actual password generation process is very straightforward.

We first need to know the password policy, and then roll a die which has the same number of sides as the number of symbols in the policy's acceptable symbols list. The roll result is used as an index into the symbols list, and the symbol at that position becomes the next character in the password. Repeat for as many characters as the password needs - again, this is defined by the password policy.