tags:

views:

144

answers:

7

At the moment I do this:

    public static class Crypto
    {
        public static string Encode(string original)
        {
            var md5 = new MD5CryptoServiceProvider();
            var originalBytes = Encoding.Default.GetBytes(original);
            var encodedBytes = md5.ComputeHash(originalBytes);

            return BitConverter.ToString(encodedBytes);
        }
    }

I hear that I should use some key to encode stuff. Should I? Is it needed here? How to do this?


I ended up doing this http://encrypto.codeplex.com/ (sha1managed + random salt)

+1  A: 

MD5 isn't an encryption algorithm, but a hashing algorithm and as such doesn't require a key. It also means that you can't reverse (/de-hash) the process. Hashing only works one way and is usefull when you have to original (unhashed) data to compare the hash to.

edit: if you do want to really encrypt your data in a reversable way. Try to look into AES encryption for example.

Laurens Ruijtenberg
I think he's talking about hashing a password regarding to the title "encode password to md5" although it's not very clear :)
sled
Please do not recommend a crypto like AES for passwords.
Jonas Elfström
why would you want to encrypt a password at all?
sled
-1: Your first statement is misleading because it suggests it would be secure enough not to use a salt, which is the whole point of the question. See sled's answer also.
chiccodoro
@above: Well the writer of this question clearly does not know the difference between a hash and encryption. You simply CAN NOT salt an MD5 password in the encryption sense of the word (at most you can append some extra characters to it, but that doesn't make it more secure perse). So it's important to know the difference, which I am trying to explain. AES btw was just an example. I didn't say it was the most secure option.
Laurens Ruijtenberg
+5  A: 

Hi,

what you're talking about is called a "salt" this is a sequence of random data which you append to the original plain text string. This is commonly used for passwords, preventing rainbow table / dictionary attacks.

Read up on this on: http://en.wikipedia.org/wiki/Salt_%28cryptography%29

For C# there's a good article: http://www.aspheute.com/english/20040105.asp

sled
Also, http://codahale.com/how-to-safely-store-a-password/
Douglas
@Douglas, this is a strong point, didn't know that yet. Should be a separate answer.
chiccodoro
@chic - It's included in the link in my answer.
Kyle Rozendo
+2  A: 

You should use Base64 encoding for representation. I.e.:

StringBuilder hash = new StringBuilder();

for (int i = 0; i < encodedBytes.Length; i++)
{
    hash.Append(encodedBytes[i].ToString("X2"));
}

This represents a string, rather than using a bit converter, which is the string representation of bytes directly (and cannot be reversed back to bits easily).

A couple of notes (please read this):

  • MD5 is a non-reversible hashing function (and not a great one at that)
  • If you are actually wanting to encrypt passwords using key-based encryption, such as AES, don't. Use the hashing method, but use a stronger one. Have a look at this answer here for more information on stengthening passwords.

Another note, in your implementation you can access the IDisposable interface, I.e.:

public static string Encode(string original)
{
    byte[] encodedBytes;

    using (var md5 = new MD5CryptoServiceProvider())
    {
        var originalBytes = Encoding.Default.GetBytes(original);
        encodedBytes = md5.ComputeHash(originalBytes);
    }

    return Convert.ToBase64String(encodedBytes);
}
Kyle Rozendo
Good point about base64 encoding but your example uses base16, or hex, encoding.
GregS
@Greg - Good point, my mistake. Fixed.
Kyle Rozendo
A: 

I'd love to see your Decode implementation.

Visage
ppl said that is not possible, and not needed actually
Omu
Sarcasm is not useful, just say that 1. Hashes are irreversible and 2. You cannot reverse from a BitConverter.
Kyle Rozendo
+1  A: 

Since SHA is considered more safe than MD5 I would recommend using it.

byte[] data = new byte[SALT_SIZE+DATA_SIZE];
byte[] result;
SHA256 shaM = new SHA256Managed();
result = shaM.ComputeHash(salt+data);
Jonas Elfström
A: 

I posted this link in a comment to sled's answer, but worth its own post.

http://codahale.com/how-to-safely-store-a-password/

It sounds like you've been given advice to salt your password hashes (I think you're calling the salt a "key"). This is better than just a hash, since it makes rainbow tables useless. A rainbow table takes a wide range of possible passwords (eg, a range of passwords, like a rainbow has a range of colours) and calculates their md5 hashes up-front. Then, to reverse an md5, simply look the md5 up in the table.

However, the advice is rapidly getting out of date. Hardware is now fast enough that rainbow tables are unnecessary: you can compute hashes really quickly, it's fast enough to just brute force the password from scratch every time, especially if you know the salt. So, the solution is to use a more computationally expensive hash, which will make a brute force much much slower.

The gold-standard tool to do this is bcrypt.

Douglas
A: 

Here are a couple points that expand on the ones in @Kyle Rozendo's answer.

  1. You should avoid using the default encoding Encoding.Default. Unless you have a good reason to do otherwise, always use UTF-8 en/de-coding. This is easy to do with the .NET System.Text namespace.
  2. MD5 output is unconstrained binary data and cannot be reliably converted directly to a string. You must use a special encoding designed to convert from binary output to valid strings and back. @Kyle Rozendo shows one method; you can also use the method in the System.Convert class.
GregS