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.
Related
hey guys i wanted to know to create a decrypt function for this crypt function :
public static string CreateHash(string unHashed)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.ASCII.GetBytes(unHashed);
data = x.ComputeHash(data);
return System.Text.Encoding.ASCII.GetString(data);
}
there is any way to decrypt function ?
hashes i got is like : ??????7hYkr?4??w
MD5 is a hash function.
So it's only one way: there is no practical way to decrypt it.
Read the introduction of the wikipedia article about cryptographic hash functions to understand how those behave.
However, if you have passwords encrypted with this function, and you want to check that a user provided password matches, you can encrypt the user provided string, and compare the result with the encrypted blob that is in your database (which is the most common use for those function).
I am using the function below to encrypt password and store it into my database. Now I need to decrypt it back and compare it with the login user. Please help me.
public static string encrypt_string_using_MD5(string s)
{
byte[] byte_array = System.Text.Encoding.Default.GetBytes(s);
System.Security.Cryptography.HashAlgorithm alg =
System.Security.Cryptography.HashAlgorithm.Create("MD5");
byte[] byte_array2 = alg.ComputeHash(byte_array);
System.Text.StringBuilder sb
= new System.Text.StringBuilder(byte_array2.Length);
foreach(byte b in byte_array2)
{
sb.AppendFormat("{0:X2}", b);
}
return sb.ToString();
}
You cannot Decrypt Hash. Hash is like signature of your original content.
What you can do is to store this Hash in database. Whenever user enters password. you compute the hash of value user entered and compare it with stored hash and if it matches then authentication is succesfull
You can not decrypt it, because it is not encrypted.
You create a hash of the text, and not an encrypted version.
A hash is like a fingerprint of data. This can be used for example to safely store passwords in a database. When someone wants to login again, you again calculate the hash and check the new hash against the one the in database to see if they match. If they do, then the password is the same and the user can login.
A good explanation can be found at http://www.securityinnovationeurope.com/blog/whats-the-difference-between-hashing-and-encrypting
Hence you use MD5, it's irreversible. Why are you sending passwords as plain text anyway...?
Either way, when comparing values (one plain, one hashed) hash the plain one and compare that.
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.
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
I'm using the code below to save a password to the registry, how do I convert it back? The code below isn't mine but it encrypts well.
Thanks
using System.Security.Cryptography;
public static string EncodePasswordToBase64(string password)
{ byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] dst = new byte[bytes.Length];
byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
SHA1 is a hash algorithm, not an encryption algorithm. A hash algorithm is a one-way function which transforms data into a hash of that data, but the original data cannot be gotten back from the hash. An encryption algorithm is a two-way function which transforms data into encrypted data, and the encrypted data can then be transformed back into the original data.
To securely store a password so that it can be read back, use the ProtectedData class.
public static string ProtectPassword(string password)
{
byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] protectedPassword = ProtectedData.Protect(bytes, null, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(protectedPassword);
}
public static string UnprotectPassword(string protectedPassword)
{
byte[] bytes = Convert.FromBase64String(protectedPassword);
byte[] password = ProtectedData.Unprotect(bytes, null, DataProtectionScope.CurrentUser);
return Encoding.Unicode.GetString(password);
}
Take whatever the user enters as a password to gain access to the system, encrypt it the same way and then compare the encrypted values, that's the normal approach. I'm pretty sure that SHA1 is a trapdoor encryption, i.e. can't be back-tracked.
You don't.
SHA1 is a hash, not encryption. It is a one-way operation; conversion back is not possible.
(Ok this is not strictly true; if you have a table of possible SHA1 values and plain text values, a rainbow table then you might be luck)
Also you should be salting your hashes, because you are, right now, vulnerable to rainbow table attacks. Jeff talks about this a little more on his blog
Okay, so I know this isn't answering your specific Q, but why do you want to convert it back?
If it's to compare in order to provide authentication, the standard approach is to encrypt this text ALSO, and compare the stored password to the supplied password.
This is more secure as it means that the original password never needs to be decrypted.
I think one of the points of using hashes is that they can't be computed back.
As someone else said, calculate the hash from the user's password and compare to the stored hash value.
In order to use the System.Security.Cryptography.ProtectedData class, you must add a reference to System.Security to your project.
(Right mouse click on the References folder, choose "Add Reference...", find System.Security on the .NET Tab)
Um, just curious but wouldn't that return the same hash for all passwords of the same length?
Using your own code snippet above, what you want to do is call that method when the user initially chooses a password - but add to the password what is called a salt somewhere in the password string (usually at the beginning or end). Then, when the user is attempting to authenticate later, they enter their password, you run that one along with the hash through this same method and if the two hashes are equal, it's a statistically excellent chance the passwords are equal and valid.
This being said, SHA1 is known to have weaknesses and you should choose a stronger algorithm. If you want to stay in the SHA family, SHA512 is pretty good.
You want to use encryption not hashing. SHA is fine but use the encryption methods for it. The problem with encryption is always where to put the key for it. You didn't mention whether this was a workstation or server you were doing this on. On a server, I find it better to just use ACL's to restrict access to the reg key. Admins can usually access the encryption key anyway...you have to have some trust somewhere. On a workstation then you can go with encryption and store the key in code or use a certificate and restrict access to it at least in a corp environment...not for sale software).
You can use the ProtectedData class but be aware that it uses user profiles for its key usage and as such you have to make sure you are impersonating the user who has the profile with the key you need. This may or may not be trivial and may or may not cause headaches and security issues.
I noticed the recent addition of the XMLEncryptedData class. For encrypting data to an XML file, is the XMLEncryptedData method more desirable than the DPAPI method?