Sat, 5 September 2009

There are a lot of passwords in my head from numerous sites of which I am a member. I try not to use the same password for any two sites because very often the password I supply is stored in plain text and is therefore available to anyone who can access the sites database. Developers should never allow this to happen, and no one, but you, should ever know your password. As a rule of thumb, if you can request an e-mail which contains your password then it is likely to be stored without encryption or the wrong type.

One-way Cryptographic Functions

The best way to store a password is as a Hash, this is a one way cryptographic function that will always give the same result for the same input, so to check a password is valid you simply Hash the input and compare it to the stored value. This means that only the user entering the password will know what it is, the storage will only contain the Hash. This is the way Windows stores passwords.

.NET Hashing

This is a trivial task, all you need is in the framework and with a simple extension added to the string object, hashing is as easy as falling off a log.

Hashing Function Implementation
public static class StringExtensions {

    /// <summary>
    /// <para>Hash a value</para>
    /// </summary>
    public static string Hash(this string value) {
        return value.Hash(false);
    }

    /// <summary>
    /// <para>Hash a value</para>
    /// </summary>
    public static string Hash(this string value, bool base64Encode) {
        var service = new MD5CryptoServiceProvider();
        var bytes = service.ComputeHash(Encoding.Default.GetBytes(value));

        return base64Encode
            ? Convert.ToBase64String(bytes)
            : Encoding.Default.GetString(bytes);
    }
}

A Base64 encoded string will play nice with all databases and xml, so this function contains the option to use it.

Usage
var hash = "Test".Hash(true); // Get a Base64 Hash
	

The Forgotten Password?

So what happens when your user forgets their password?

Well there are a few golden rules for this too, given the assumption that the users e-mail is secure enough;

  1. Don't reset someone's password, it may not be them requesting the lost password action, leave the user's password untouched.
  2. Have another field in the user storage to store a temporary hash, which you send attached to a link which will identify them and let them back on the site.
  3. Make sure that the temporary hash is removed when they enter the site, it should only be usable once. They can always try again.
  4. Store a request date and time, give the link a window of time to work in, old links should fail, tell the user what this time to respond is.
  5. If they request a link again, i.e. a valid hash is in place, don't create a new one, sometimes e-mail delays can deliver a message out of sequence which can confuse the user when their link doesn't work because its been overwritten.
  6. Make sure the user chooses a new password immediately on entering your site.

Development, Security

Comments

13 Jun 2010

Ant

Please feel free to add your comments here


(required)


(required, not shown)

(required)