Encode password to MD5 using keys - c#

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)

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 .NET System.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

Related

PHP and C# MD5 crypt does not give the same output?

This is the encryption I have when people register on my site:
$salt = generateSalt();
$hashedPassword = crypt($userPass, $salt);
and here is my generateSalt function:
function generateSalt() {
$salt = uniqid(mt_rand(), true);
$salt = '$1$' . $salt;
return $salt;
}
When I encrypt a password with this I get for example:
$1$92999442$AK4yZPjnj6BKc9yj4CXKu1
But when I crypt the same password on C# with this function:
hashedPassword = GenerateMD5(uName, salt);
GenerateMD5 function:
public String GenerateMD5(String input, String salt)
{
Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input + salt);
System.Security.Cryptography.MD5Cng md5hashstring = new System.Security.Cryptography.MD5Cng();
byte[] hash = md5hashstring.ComputeHash(bytes);
string hex = BitConverter.ToString(hash).Replace("-", string.Empty);
return hex;
}
I get a complete different output. With the same password and the same salt I get this output:
9DE11D48C3F7DF1BF89FC76D755A2596
What function should I use in PHP and C# to get the same output?
Because you're using two completely different algorithms. In PHP you're using crypt() which uses DES, and in C# you're using MD5. They're never going to produce the same output. If you want the same output, you should use md5() in PHP instead of crypt()
Also, don't use MD5, it's deprecated. You should be using at least SHA-2 now
http://php.net/md5
http://blogs.msdn.com/b/csharpfaq/archive/2006/10/09/how-do-i-calculate-a-md5-hash-from-a-string_3f00_.aspx
and adding a random salt to your input is part of them problem. you'll end up with a different input every time, hence a different hash output.
If I were you I'd consider using password_hash instead. Does all that crypt work for you in a nice, neat package, complete with random salt.
As to why your function doesn't match, you're using MD5 in your C# code. I'm no expert in C# but you should use some sort of bcrypt hashing system. There is an open source bcrypt for C# that might do the trick for you. In theory, since they use the same system, one should be able to validate the other since they all store the salt in the string. Just pluck the salt from the string and plug the password and salt into the other one and they should match.
This is so called md5crypt by Poul-Henning Kamp, not to be confused with MD5. Md5crypt for first used to protect FreeBSD passwords from bruteforce, but then became more widespread. It was incorporated into GNU libc crypt() and many programs had interfaces to this system call, including PHP, and some PHP developers made use of it. Md5crypt invokes MD5 no less than 1000 times to make brute-force harder (but nowadays md5crypt is considered outdated by its author!). I have seen implementation of md5crypt for many programming languages, this one is for C#.

how to decrypt SHA512 hash value to an actual string in c# [duplicate]

This question already has an answer here:
Vb.net Decrypt sha512 hash
(1 answer)
Closed 8 years ago.
I encrypt the password by following code
HashAlgorithm hashAlgorithm = null;
hashAlgorithm = new SHA512CryptoServiceProvider();
try
{
byte[] byteValue = Encoding.UTF8.GetBytes(source);
byte[] hashValue = hashAlgorithm.ComputeHash(byteValue);
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= hashValue.Length - 1; i++)
{
sb.AppendFormat("{0:x2}", hashValue[i]);
}
return Convert.ToString(sb);
}
catch
{
throw;
}
after that I saved it in database.
now I want to retrieve actual password by decrypting it. please help me
You hash a password and you don't encrypt it. That being said you cannot decrypt it.
Taken from here
Encryption transforms data into another format in such a way that only
specific individual(s) can reverse the transformation. It uses a key,
which is kept secret, in conjunction with the plaintext and the
algorithm, in order to perform the encryption operation. As such, the
ciphertext, algorithm, and key are all required to return to the
plaintext.
while
Hashing serves the purpose of ensuring integrity, i.e. making it so
that if something is changed you can know that it’s changed.
Technically, hashing takes arbitrary input and produce a fixed-length
string that has the following attributes:
The same input will always produce the same output.
Multiple disparate inputs should not produce the same output.
It should not be possible to go from the output to the input.
Any modification of a given input should result in drastic change to the hash.
Hashing is used in
conjunction with authentication to produce strong evidence that a
given message has not been modified. This is accomplished by taking a
given input, encrypting it with a given key, hashing it, and then
encrypting the key with with the recipient’s public key and signing
the hash with the sender’s private key.
then what can I use with which I can convert output to input?
You should decrypt your data and not hash them. Encrypting and Decrypting data is a big subject. A good starting point is to read this. Generally, you have two types of encryoption, symmetric and assymmetric. So initially, read about them and then choose the one you think is suits your needs. Then try to implement it. You will make use of algorithms that are already implemented in .NET and can be used instantiating objects of the corresponding classes and calling specific methods.
However, I have to make a note here. Usually, we hash the passwords and we don't encrypt them. This is more secure. Taken from here:
Though hashing and encryption both provide valuable capabilities, for
the vast majority of situations, there is only one right option for
storing user passwords for an online application: hashing. This is a
one-way function in which a hashed value cannot be reversed to obtain
the original input value (i.e., the password). Symmetric encryption is
based on the use of an encryption key and is a reversible operation.
Anyone possessing the key can decrypt an encrypted value to obtain the
original value.

C# SHA512 / Public Static String

an annoying question today, i should know this but for the life of me i can't figure it out. I am trying to hash a password before querying the sql database. I have the hash code working fine however its inside a public static string:
public static string GetCrypt(string text)
{
string hash = "";
SHA512 alg = SHA512.Create();
byte[] result = alg.ComputeHash(Encoding.UTF8.GetBytes(text));
hash = Encoding.UTF8.GetString(result);
return hash;
}
I have two questions, one.. once it is hashed, how do i go about getting that result as when i try to access the variable "hash" it gives the error does not exist in current context. I suspect this is due to public and private classes?
Also, my other question, to have a more effective program, can i or is this already, a code where by i type it once, then can call it passing variables back and forth. sort of like, enter a password, it hashes, then passes it back.. then in another textbox pass new variable to the same hash code and get new hashed variable back?
Thanks in advance guys!
To use this method you would store the return value, like this:
string hashedString = GetCrypt(inputString);
Then use hashedString as appropriate.
However, you have some problems:
The result of alg.ComputeHash() is not a UTF-8 encoded string, so Encoding.UTF8.GetString() is very likely to throw an exception, and won't even do what you want. Consider using Convert.ToBase64String() (or convert the byte array to a hex string).
You don't salt the input string, at least not within this method. This means your database of passwords is vulnerable to rainbow table attacks. Consider using salted hashes or (better yet) an algorithm design specifically for hashing passwords, such as bcrypt, scrypt, or PBKDF2 which is built in to the framework itself.

Get the plain text back from hash code in C#

I have some simple code but I need to get back my plain text from my hash code.
private string Hash(string ToHash)
{
// First we need to convert the string into bytes,
// which means using a text encoder.
Encoder enc = System.Text.Encoding.ASCII.GetEncoder();
// Create a buffer large enough to hold the string
byte[] data = new byte[ToHash.Length];
enc.GetBytes(ToHash.ToCharArray(), 0, ToHash.Length, data, 0, true);
// This is one implementation of the abstract class MD5.
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(data);
return BitConverter.ToString(result);
}
As far as I am aware, you can't un-hash something. It simply goes against the idea of hashing. Are you sure you are not thinking about 'encrypting'? As with a symmetric or asymmetric key?
Are you trying to compare a password someone entered to the stored hash of their password? If so, then instead of trying to unhash the stored password, you just need to hash the password they enter and then compare the two hashes to see if they match.
You should not be able to reverse a hash - it is by definition a one-way function. You might be able to guess what the plaintext of an md5 hash is by using a rainbow table or brute force guessing but it is expensive and not really what you're looking for.

Is there an alternate hashing algorithm to MD5 for FIPS-enabled systems?

Whenever I try to use MD5 on a Windows XP machine that has FIPS enabled, I am getting a System.InvalidOperationException.
Is there an alternate algorithm that I should use instead of MD5 on FIPS?
MD5 is not FIPS compliant. You can use instead of the MD5 one of the following hashing algorithms:
HMACSHA1
MACTripleDES
SHA1CryptoServiceProvider
When you enforce FIPS compliance in the Windows security policy settings, you're asserting that you are only going to use FIPS-certified encryption and hashing algorithms. MD5 is not one of these approved hashing algorithms, and that's why the exception is being thrown.
The workaround is simple: choose a different hashing algorithm. The .NET Framework provides plenty of other options in the System.Security.Cryptography namespace. Select one of the SHA family of algorithms. I can't imagine any reason you would have to use MD5 as opposed to one of the alternatives.
You can use MD5Digest from Org.BouncyCastle.Crypto.Digests
MD5Digest hash = new MD5Digest();
public byte[] Hash(byte[] input)
{
hash.BlockUpdate(input, 0, input.Length);
byte[] result = new byte[hash.GetDigestSize()];
hash.DoFinal(result, 0);
return result;
}
public string Hash(string input)
{
var data = System.Text.Encoding.Unicode.GetBytes(input);
hash.BlockUpdate(data, 0, data.Length);
byte[] result = new byte[hash.GetDigestSize()];
hash.DoFinal(result, 0);
return Hex.ToHexString(result).ToUpper();
}
For cryptographic hashing purposes, you can use SHA1, SHA2, or SHA3, with HMAC if desired.
If you want to use MD5 for non-cryptographic purposes, then that is fine, but you will need to provide your own implementation. Examples include:
Hashing files to determine duplicates
Internal hash table implementations
Validating files from their provided MD5 hashes
The last point is questionable; validating SHA1/SHA2 hashes would be better, and it depends on the validation (e.g. was it corrupted in transit vs. packet authentication).

Categories