About This Site  | Contact Us  | About Me
Increase font
Play Famous Card Game[PHARASH]

SHA1, MD5, SHA256 and some C# code snippet

 

Introduction

Storing raw passwords in the database is like inviting experienced hackers to come and crack our database table containing important and sensitive information of our clients. Studies have shown that the experienced hackers and crackers can easily break the database table containing raw passwords by finding some of the flaws in the underlying operating system or in the application software, and finally gaining access to the database. However, the current trend in the software development is that the raw password is not saved in the database directly, but the raw password supplied by the users are stored as hash value in the database. Furthermore, recent events have shown that to securely store the passwords they must be salted with some random vlaues ----generated by using fine algorithm - before saving them into the database. In this article, I would discuss about some of the popular algorithms in the field of password hashing. In the processby using some advanced algorithm such as SHA1 or MD5 converted into hash value – and the hash values are stored in the database. In this article, I briefly discuss some of the issues pertaining to the hashing of the password and some of the popular hashing algorithms such as SHA1, MD5, and strengths and the drawbacks these algorithms have, and finally,by following Microsoft recent hint, talk about implementing SHA256 in the current application. Whenever possible, I would like to include some C# code to follow my essay.

Differences between SHA1 and MD5


SHA1

MD5

The performance is a little slow because it uses 160-bit message digest rather than a 128-bit one. A little faster compared to SHA1.
One way Hash. Note: this type of algorithm does not allow to get the oringinal value from the hashed value. One way Hash
A little bit slower than MD5. A little bit faster compared to SHA1
SHA1 returns 40 hexadecimal characters. MD5 returns the 32 hexadecimal characters.
Takes in as input the arbitrary message size and converts to 160-bit fingerprint. Takes in as input an arbitrary message size and converts to 128-bit fingerprint.

What is Salt and Why is it needed?

Most common question that is raised so frequently whenever developers do discuss about Salt and hash is the salt size. The larger the salt size, the better the chances that it would be random. In other words, the chances of two random numbers being the same is almost impossible. Code below shows some of the methods of generating salt value and finally appending the salt value to the original password supplied by the user before hashing

private const int HASH_SALT_LENGTH = 32; private static bool CheckHash(string password, string hashed) { string salt = hashed.Substring(0, HASH_SALT_LENGTH); string tryHash = salt + Cipher.Hash(salt + password); return tryHash == hashed; } private static string Hash(string password) { string salt = GetRandomHexadecimal(); return salt + Cipher.Hash(salt + password); } private static string GetRandomHexadecimal() { string characters = "0123456789abcdef"; StringBuilder buffer = new StringBuilder(); int length = HASH_SALT_LENGTH; Random random = new Random(); for (int n = 0; n

Vulnerabilities of the SHA1

  • SHA1 is easy to compute in one direction , but it is extremely difficult to reconstitute any message from the hash value.
  • in SHA1, the collusion was found just by using 2^69 numbers of operations, far fewer than 2^80 operations previously thought needed to find the collision.
  • Drawbacks of the MD5

  • For MD5, it required only 2^40 operations to find a collision.

Definition of Collision
The collision occurs whenever the hash algorithm generates the same hash values after certain interval of time. The ideal algorithm would be the one that would be free from the collsion. However, that is not case. For example, even strong hashing algorithm such as SHA1 and MD5 have been found with collision after certain number of operations. For example, a collision was found in SHA1 after 2^69 times of operations.
Below is the some code example to implement these algorithms in C# using visual Studio.NET

namespace My_Hasing_Algorithm_NameSpace { public enum CipherAlgorithm { TripleDES , Rijndael } } Here is the implementation details in C#.
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace My_Hasing_Algorithm_NameSpace { public class Cipher { #region Private Static Constructor static Cipher() { if (Configuration.Instance != null && Configuration.Instance.Cipher != null) { byte[] privateKey = FromHexaDecimal(Configuration.Instance.Cipher.PrivateKey); byte[] initializationVector = FromHexaDecimal(Configuration.Instance.Cipher.InitializationVector); _defaultKey = privateKey; _defaultInitializationVector = initializationVector; _hashSalt = Configuration.Instance.Cipher.HashSalt; _defaultAlgorithm = Configuration.Instance.Cipher.DefaultSymmetricAlgorithm; _defaultHashingAlgorithm = Configuration.Instance.Cipher.DefaultHashingAlgorithm; } } #endregion #region Private Constructor private Cipher() { } #endregion #region Static Fields private readonly static byte[] _defaultInitializationVector = new byte[] { 11, 114, 130, 134, 22, 11, 110, 78, 99, 145, 221, 234, 11, 12, 11, 201 }; private readonly static byte[] _defaultKey = new byte[] { 201, 1, 12, 51, 1, 25, 11, 15, 11, 198, 11, 112, 114, 3, 21, 11 }; private static string _hashSalt = ""; private static CipherAlgorithm _defaultAlgorithm = CipherAlgorithm.Rijndael; private static CipherHashingAlgorithm _defaultHashingAlgorithm = CipherHashingAlgorithm.MD5; #endregion #region Public Static Methods public static string Encrypt(string text) { return Encrypt(text, _defaultAlgorithm); } public static string Encrypt(string text, CipherAlgorithm algorithm) { return Encrypt(text, algorithm, _defaultKey, _defaultInitializationVector); } public static string Encrypt(string text, CipherAlgorithm algorithm, string key, string initializationVector) { return Encrypt(text, algorithm, FromHexaDecimal(key), FromHexaDecimal(initializationVector)); } public static string Encrypt(string text, CipherAlgorithm algorithm, byte[] key, byte[] initializationVector) { return DoEncrypt(text, key, // have to clone the _initializationVector since a *bug* in // the framework causes it to zeroed out when the provider is Disposed. (byte[]) initializationVector.Clone(), algorithm ); } public static string Decrypt(string text, CipherAlgorithm algorithm, string key, string initializationVector) { return Decrypt(text, algorithm, FromHexaDecimal(key), FromHexaDecimal(initializationVector)); } public static string Decrypt(string text, CipherAlgorithm algorithm, byte[] key, byte[] initializationVector) { return DoDecrypt(text, key, // have to clone the _initializationVector since a *bug* in // the framework causes it to zeroed out when the provider is Disposed. (byte[]) initializationVector.Clone(), algorithm ); } public static string Decrypt(string encryptedHexadecimal) { return Decrypt(encryptedHexadecimal, _defaultAlgorithm); } public static string Decrypt(string encryptedHexadecimal, CipherAlgorithm algorithm) { try { return Decrypt(encryptedHexadecimal, algorithm, _defaultKey, _defaultInitializationVector); } catch (Exception e) { throw new CipherException("Failed to decrypt.", e); } } public static string Hash(string input) { return Hash(input, _defaultHashingAlgorithm); } public static string Hash(string input, CipherHashingAlgorithm algorithm) { string salt = _hashSalt; string dataToHash = salt != null ? salt + input : input; HashAlgorithm hash = null; switch (algorithm) { case CipherHashingAlgorithm.SHA1: hash = new SHA1Managed(); break; case CipherHashingAlgorithm.MD5: hash = new MD5CryptoServiceProvider(); break; } hash.Initialize(); ASCIIEncoding encoding = new ASCIIEncoding(); byte[] data = encoding.GetBytes(dataToHash); byte[] digest = hash.ComputeHash(data); return ToHexaDecimal(digest); } #endregion #region Private Static Methods private static string ToHexaDecimal(byte[] bytes) { if (bytes == null) { return ""; } StringBuilder buffer = new StringBuilder(); int length = bytes.Length; for (int n = 0; n

Even though the code above works great, but as the attacks becomes more fatal and sophisticated and news starts circulating that 128-bit SHA1 has been compromised, Microsoft is suggesting its customers and affiliates to use SHA256 hashing algorithm to become more robust and secure from ever-increasing security threats. Some of the codes that must be changed to incorporate the SHA256 for the code above are enumerated below.

  • Find the array named _defaultKeysize and make it to hold 32-bytes instead of existing 16-Bytes
  • FInd the array named _defaultInitializationVecotr and make it to hold 32-bytes instead of existing 16-Bytes
  • Add one more field named SHA256 inside the enum Type HashingAlgorithm as follow: namespace My_Hasing_Algorithm_NameSpace { public enum HasingAlgorithm { SHA1 , MD5 ,SHA256 } }
  • There should be some modifications inside the function Hash() as follows: public static string Hash(string input, CipherHashingAlgorithm algorithm) { string salt = _hashSalt; string dataToHash = salt != null ? salt + input : input; HashAlgorithm hash = null; switch (algorithm) { case CipherHashingAlgorithm.SHA1: hash = new SHA1Managed(); break; case CipherHashingAlgorithm.MD5: hash = new MD5CryptoServiceProvider(); break; case CipherHashingAlgorithm.SHA256: hash = new SHA256Manages(); break; } hash.Initialize(); ASCIIEncoding encoding = new ASCIIEncoding(); byte[] data = encoding.GetBytes(dataToHash); byte[] digest = hash.ComputeHash(data); return ToHexaDecimal(digest); }

    Microsoft Position in Hashing

  • Microsoft recommends not using some of the methods related to the following classes: MD4, MD5, DES, SHA1 because of the increasingly sophisticated attacks.
  • Microsoft is recommending to use (SHA)256, and AES
  • Microsoft has taken steps to deprecate the use of MD5 and SHA1 in favor of SHA256 within their own products.
  • Conclusion

    Even though SHA1, and MD5 are strong encryption algorithm, recent studies have shown that it is possible to find the collisions in these algorithms after certain interval. So the current trend in the software developement is to move to the more powerful algorithm such as SHA256 or the variants of the SHA1. Furthermore, Microsoft is also suggesting its affiliates to move to the powerful encryption algorithm to avoid possible attacks such as brute force attacks. About the Author
    Shiva Adhikari : Software Engineer APS Healthcare Silver Spring Md working in C#, ASP.NET, VB.NET, JSON, JavaScript, Ajax etc.
    Education : MS in Computer Science , Frostburg State University.





    Leave comments

        Comments








    website, Copyright © 2008-2010