Encode password to MD5 using keys
At the moment I do this:
public static class Crypto
{
public static string Encode(string or开发者_开发知识库iginal)
{
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)
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
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);
}
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);
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.
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
.
Here are a couple points that expand on the ones in @Kyle Rozendo's answer.
- 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 .NETSystem.Text
namespace. - 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.
Class example:
using System.Security.Cryptography;
using System.Text;
private static string MD5(string Metin)
{
MD5CryptoServiceProvider MD5Code = new MD5CryptoServiceProvider();
byte[] byteDizisi = Encoding.UTF8.GetBytes(Metin);
byteDizisi = MD5Code.ComputeHash(byteDizisi);
StringBuilder sb = new StringBuilder();
foreach (byte ba in byteDizisi)
{
sb.Append(ba.ToString("x2").ToLower());
}
return sb.ToString();
}
MessageBox.Show(MD5("isa")); // 165a1761634db1e9bd304ea6f3ffcf2b
精彩评论