How to Use SHA1 or MD5 in C#?(Which One is Better in Performance and Security for Authentication)

62,492

Solution 1

Not sure what you mean by automatically, but you should really use SHA256 and higher. Also always use a Salt (code) with your hashes. A side note, after time has passed, using hardened hashes is far better than using a plain speed-based hashing function. I.e.: hashing over a few hundred iterations, or using already proven hashing functions such as bcrypt (which is mentioned below I believe). A code sample for using a SHA256 hash function in .NET is as follows:

byte[] data = new byte[DATA_SIZE];
byte[] result;

using(SHA256 shaM = new SHA256Managed()) {
    result = shaM.ComputeHash(data);
}

Will do the trick for you using SHA256 and is found at MSDN.


Sidenote on the "cracking" of SHA1: Putting the cracking of SHA-1 in perspective

Solution 2

SHA1 is stronger than MD5 so if you have the choice it would be better to use it. Here's an example:

public static string CalculateSHA1(string text, Encoding enc)
{
    byte[] buffer = enc.GetBytes(text);
    SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
    return BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");
}

Solution 3

Both are too fast to be used, directly at least. Use Key Strengthening to "slow down" the password hashing procedure. Speed is the unfortunately the enemy to password security.

How slow is slow enough? Slowing down a password hash from ~microseconds to ~hundreds of milliseconds will not adversely affect the perceived performance of your application... but will make cracking passwords literally a hundred thousand times slower.

View this article for details: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

The problem is that MD5 is fast. So are its modern competitors, like SHA1 and SHA256. Speed is a design goal of a modern secure hash, because hashes are a building block of almost every cryptosystem, and usually get demand-executed on a per-packet or per-message basis.

Speed is exactly what you don’t want in a password hash function.

... snip ...

The password attack game is scored in time taken to crack password X. With rainbow tables, that time depends on how big your table needs to be and how fast you can search it. With incremental crackers, the time depends on how fast you can make the password hash function run.

That said, use BCrypt. SCrypt was recently developed, but I doubt that any stable (or production ready) libraries exist for it yet. Theoretically, SCrypt claims to improve upon BCrypt. "Building your own" is not recommended, but iterating MD5 / SHA1 / SHA256 thousands of times ought to do the trick (ie: Key Strengthening).

And in case you don't know about them, be sure to read up on Rainbow Tables. Basic security stuff.

Solution 4

From MSDN

byte[] data = new byte[DATA_SIZE];
byte[] result; 

SHA1 sha = new SHA1CryptoServiceProvider(); 
// This is one implementation of the abstract class SHA1.
result = sha.ComputeHash(data);

Solution 5

I'd like use these things.

MD5, SHA1/256/384/512 with an optional Encoding parameter.

Othere HashAlgorithms.Thanks to Darin Dimitrov.

public static string MD5Of(string text)
{
    return MD5Of(text, Encoding.Default);
}
public static string MD5Of(string text, Encoding enc)
{
    return HashOf<MD5CryptoServiceProvider>(text, enc);
}
public static string SHA1Of(string text)
{
    return SHA1Of(text, Encoding.Default);
}
public static string SHA1Of(string text, Encoding enc)
{
    return HashOf<SHA1CryptoServiceProvider>(text, enc);
}

public static string SHA384Of(string text)
{
    return SHA384Of(text, Encoding.Default);
}
public static string SHA384Of(string text, Encoding enc)
{
    return HashOf<SHA384CryptoServiceProvider>(text, enc);
}

public static string SHA512Of(string text)
{
    return SHA512Of(text, Encoding.Default);
}
public static string SHA512Of(string text, Encoding enc)
{
    return HashOf<SHA512CryptoServiceProvider>(text, enc);
}

public static string SHA256Of(string text)
{
    return SHA256Of(text, Encoding.Default);
}
public static string SHA256Of(string text, Encoding enc)
{
    return HashOf<SHA256CryptoServiceProvider>(text, enc);
}

public static string HashOf<TP>(string text, Encoding enc)
    where TP: HashAlgorithm, new()
{
    var buffer = enc.GetBytes(text);
    var provider = new TP();
    return BitConverter.ToString(provider.ComputeHash(buffer)).Replace("-", "");
}
Share:
62,492

Related videos on Youtube

Sajad Bahmani
Author by

Sajad Bahmani

Favorite Languages : Java , Scala , Bash , C/C++ , Python Favorite IDE : IntelliJ IDEA , Netbeans Favorite Editor : VSCode , Vim

Updated on August 12, 2020

Comments

  • Sajad Bahmani
    Sajad Bahmani over 3 years

    In C# how we can use SHA1 automatically?
    Is SHA1 better than MD5?(We use hashing for user name and password and need speed for authentication)

    • Guillaume
      Guillaume over 14 years
      I would advice SHA1 with salt.
    • Mark Byers
      Mark Byers over 14 years
      I would advise SHA256. SHA1 is now considered to be weak.
    • Cipi
      Cipi over 13 years
      I would advise RIPEMD160. Heres how to use it in C# msdn.microsoft.com/en-us/library/…
    • snemarch
      snemarch over 13 years
      How is authentication speed a problem? Even using key strengthening (which you should!), authentication will still run in hundred of milliseconds. Also, be sure to use per-user salts, this is more important than MD5 vs SHA.
    • CodesInChaos
      CodesInChaos about 13 years
      Typically you want bad performance for password hashing. You typically use a scheme that slows hashing down to slow brute force attacks down.
    • AviD
      AviD about 6 years
      Please note: The accepted answer is very wrong, especially now that it is several years later. Using the given answer WILL expose your system and users to needless risks, as these passwords can be (almost trivially) retrieved and used to spoof the users in an impersonation attack. Please see @Dragontamer5788's answer below, regarding bcrypt/scrypt/etc.
  • Kyle Rosendo
    Kyle Rosendo over 13 years
    @quantum - At the time there wasn't as much info on this as there is now. Removed SHA1 and added a link to "Putting the cracking of SHA1 into perspective."
  • Dragontamer5788
    Dragontamer5788 over 13 years
    The MD5 vulnerabilities do not relate to passwords. It allows the attacker to create a collision, provided that he knows the original plaintext. While this is a very bad thing for message authentication, this is not an issue for passwords. (where the original plaintext is (hopefully) unavailable to the attacker). On the other hand, see nsa.unaligned.org for SHA1 and MD5 password cracking. Notice, he does NOT use any algorithmic vulnerabilities... he just uses the fact that SHA1 and MD5 are fast. Any fast hash algorithm (SHA256 included) is vulnerable without key strengthening.
  • Dragontamer5788
    Dragontamer5788 over 13 years
    I just noticed that this here is now the accepted answer. If anyone didn't realize it from my previous comment, simply using SHA256 directly like this creates a vulnerability in your password hash. It is no better than MD5 or SHA1. No one will use the MD5 vulnerabilities to crack your passwords. Brute Forcing is so fast today, that you can brute force the entire 8-character sequence in a day. You need to choose a slower algorithm than SHA256, SHA1, and MD5 to remain safe. Again, key strengthen your hash algorithm by iterating over it, or choose a slower algorithm like BCrypt or SCrypt.
  • Kyle Rosendo
    Kyle Rosendo over 13 years
    @Drag - No doubt that Bcrypt / Password strengthening is a better option, however with the added salt (which can be taken to a salted password of whatever size of your choosing (64-character+ is good)) with a decent 3-try delay log-in system makes brute forcing an untenable method for the cracker. Emphasis on the decent log in system here. If you delay login for 5 minutes, or get verification before continuing, this will do the trick. When I answered this back in November, I quite simply answered the question. I should have also mentioned what you have.
  • Dragontamer5788
    Dragontamer5788 over 13 years
    @Kyle: I figure we're talking about offline attacks. If someone steals your database and then injects it into a cluster built out of PS3s or GPUs or FPGAs to crack the passwords. You cannot talk about SALTS (which are designed to prevent offline rainbow table attacks), without talking about key strengthening (which are designed to prevent offline incremental cracker attacks)
  • Dragontamer5788
    Dragontamer5788 over 13 years
    @Kyle: I argue, we've always been talking about offline attacks. Otherwise... I fail to see where the stated MD5 and SHA1 vulnerabilities come into play with an online attack. Salts also do not matter with online attacks... Its impossible to use a rainbow table during online attacks.
  • Dragontamer5788
    Dragontamer5788 over 13 years
    @Kyle: All rainbow table attacks are offline by definition. You are attacking the database by attempting to reverse the hashes. However, in an online attack, you do not have access to the hashes of the passwords. IF you have access to the hash values of the passwords, then by definition, you are conducting an offline attack. Thus, by definition, all rainbow table attacks are offline. Its just what a rainbow table attack is.
  • Dragontamer5788
    Dragontamer5788 over 13 years
    @Kyle: I don't expect to be tripped up by simple terminology on a site like this... an online attack has nothing to do with the web. "Network Security" by Kaufman et. al, page 217. "One way of guessing passwords is simply to type passwords at the system that is going to verify the password". This is the definition of an online attack. Now that we both know what I'm talking about, please tell me how you plan to use Rainbow Tables in this kind of setup.
  • Dragontamer5788
    Dragontamer5788 over 13 years
    @Kyle: So that I'm more thorough about this... "In contrast, in an offline attack, an intruder can capture a quantity X that is derived from a password in a known way. Then the intruder can, in complete privacy, use an arbitrary amount of compute power to guess passwords, convert them in the known way, and see if X is produced." Same page / reference as the online attack quote above. As I noted before, Rainbow Tables are by definition, an offline attack.
  • Kyle Rosendo
    Kyle Rosendo over 13 years
    @Drag - I'm not going to bother anymore, especially once the facetiousness sets in. I have deleted my posts, bar my first. Everyone can read your points and enjoy.
  • Dragontamer5788
    Dragontamer5788 over 13 years
    @Kyle: While I would much prefer to finish the conversation, I respect your wishes to pull out. If I were to blame anything, I blame the stupid 600 character limit to these comments. Its far too short for me to unambiguously represent my ideas. I'm sure there was some sort of miscommunication somewhere along this line, and it is a shame that we didn't finish hashing out the details. I give you my best regards, and hope that our next debate will be more fruitful.
  • Kyle Rosendo
    Kyle Rosendo over 13 years
    @Drag - We can take it to IRC some time :)
  • CodesInChaos
    CodesInChaos about 13 years
    I think you should rather post a code-sample with Rfc2898DeriveBytes that plain SHA1.
  • barrypicker
    barrypicker over 11 years
    why do you replace "-" with ""?
  • andreapier
    andreapier about 11 years
    This always gives me the correct hash, but in upper case, which is not the right result actually... Any idea?
  • si618
    si618 over 10 years
    See stackoverflow.com/a/5340599/44540 i.e. BitConverter.ToString returns a hex string, which explains both the hypen replacement and uppercase issue.
  • cateyes
    cateyes almost 9 years
    SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider(); should be wrapped in a using statement I think, as one of its base classes implements IDisposable.
  • AviD
    AviD about 6 years
    Please note: This answer is wrong in the context of protecting passwords, especially now that it is several years later. Using the information provided in this answer WILL expose your system and users to needless risks, as these passwords can be (almost trivially) retrieved and used to spoof the users in an impersonation attack. @Dragontamer5788 is very correct nowadays (as they were then), bcrypt/scrypt/PBKDF2/Argon2 are the only decent solutions to protect passwords.