Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setup additional hash algorithm

Tags:

c#

hash

I'm really new with C# and I'm looking at code that my predecessor generated. Here's the code:

public static string ComputeHash(string plainText,
                                     string hashAlgorithm, byte[] saltBytes)
    {
        if (saltBytes == null)
            saltBytes = CreateSalt(8);

        // Convert plain text into a byte array.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        // Allocate array, which will hold plain text and salt.
        byte[] plainTextWithSaltBytes =
                new byte[plainTextBytes.Length + saltBytes.Length];

        // Copy plain text bytes into resulting array.
        for (int i = 0; i < plainTextBytes.Length; i++)
            plainTextWithSaltBytes[i] = plainTextBytes[i];

        // Append salt bytes to the resulting array.
        for (int i = 0; i < saltBytes.Length; i++)
            plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];

        // Because we support multiple hashing algorithms, we must define
        // hash object as a common (abstract) base class. We will specify the
        // actual hashing algorithm class later during object creation.
        HashAlgorithm hash;

        // Make sure hashing algorithm name is specified.
        if (hashAlgorithm == null)
            hashAlgorithm = "";

        // Initialize appropriate hashing algorithm class.
        switch (hashAlgorithm.ToUpper())
        {
            case "SHA1":
                hash = new SHA1Managed();
                break;

            case "SHA256":
                hash = new SHA256Managed();
                break;

            case "SHA384":
                hash = new SHA384Managed();
                break;

            case "SHA512":
                hash = new SHA512Managed();
                break;

            default:
                hash = new MD5CryptoServiceProvider();
                break;
        }

        // Compute hash value of our plain text with appended salt.
        byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

        // Create array which will hold hash and original salt bytes.
        byte[] hashWithSaltBytes = new byte[hashBytes.Length +
                                            saltBytes.Length];

        // Copy hash bytes into resulting array.
        for (int i = 0; i < hashBytes.Length; i++)
            hashWithSaltBytes[i] = hashBytes[i];

        // Append salt bytes to the result.
        for (int i = 0; i < saltBytes.Length; i++)
            hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];

        // Convert result into a base64-encoded string.
        string hashValue = Convert.ToBase64String(hashWithSaltBytes);

        // Return the result.
        return hashValue;
    }

    public static bool VerifyHash(string plainText,
                                  string hashAlgorithm,
                                  string hashValue)
    {
        // Convert base64-encoded hash value into a byte array.
        byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue);

        // We must know size of hash (without salt).
        int hashSizeInBits, hashSizeInBytes;

        // Make sure that hashing algorithm name is specified.
        if (hashAlgorithm == null)
            hashAlgorithm = "";

        // Size of hash is based on the specified algorithm.
        switch (hashAlgorithm.ToUpper())
        {
            case "SHA1":
                hashSizeInBits = 160;
                break;

            case "SHA256":
                hashSizeInBits = 256;
                break;

            case "SHA384":
                hashSizeInBits = 384;
                break;

            case "SHA512":
                hashSizeInBits = 512;
                break;

            default: // Must be MD5
                hashSizeInBits = 128;
                break;
        }

        // Convert size of hash from bits to bytes.
        hashSizeInBytes = hashSizeInBits / 8;

        // Make sure that the specified hash value is long enough.
        if (hashWithSaltBytes.Length < hashSizeInBytes)
            return false;

        // Allocate array to hold original salt bytes retrieved from hash.
        byte[] saltBytes = new byte[hashWithSaltBytes.Length -
                                    hashSizeInBytes];

        // Copy salt from the end of the hash to the new array.
        for (int i = 0; i < saltBytes.Length; i++)
            saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];

        // Compute a new hash string.
        string expectedHashString =
                    ComputeHash(plainText, hashAlgorithm, saltBytes);

        // If the computed hash matches the specified hash,
        // the plain text value must be correct.
        return (hashValue == expectedHashString);
    }

The company has upgraded their security standards and requires secure hashing algorithms such as SHA-1, 3DES (triple DES) or AES MAC. I have no idea where to include them. Would someone please help?

like image 656
inquisitive_one Avatar asked Jan 27 '26 16:01

inquisitive_one


2 Answers

The company has upgraded their security standards and requires secure hashing algorithms such as SHA-1, 3DES (triple DES) or AES MAC.

First of all, you already have SHA-1, and that hash algorithm, although slightly weaker than SHA-256/512, is still pretty good. Sticking to SHA-512 will keep you very safe, unless you are dealing with villains which are willing to spend 10 years breaking your messages using a supercomputer.

As for the other two algorithms, 3DES is a symmetric cypher and therefore unsuitable for hashing, while MACs are created using hashing algorithms such as SHA-2 (the difference is that you hash you a "secret key" along your message (something like "fixed salt") to ensure its authenticity. AES is also a symmetric cypher, and therefore also unsuitable for hashing.

Tell the guys from your company to check this page and settle for one of these hashing functions (in other words: don't change anything). If you are not experienced with cryptography, chances are you might make the system insecure regardless of your hashing choice.

like image 159
Groo Avatar answered Jan 29 '26 06:01

Groo


I assume by "AES MAC" you are referring to Poly1305-AES. Poly1305-AES isn't a simple hash, it needs a AES key, and a 128 bit nonce, which is used when you communicate between two entities.

3DES (Triple DES) is an encryption cipher, it doesn't ensure authentication or integrity of a message whatsoever. The only function of 3DES is to ensure confidentiality of a message.

In respect to SHA-1, you should no longer use that hash as it has been broken since 2005.

I would suggest you get a formal description of what these new security standards are. 2 of the things you listed aren't even hash algorithms, and the third is a bad choice. Of the hash algorithms listed in your current implementation SHA-256 and above should be fine (aka SHA-2 category). These don't have any published vulnerabilities I am aware of at the moment.

Side note: You probably want to use arraycopy instead of looping over the bytes.

like image 30
Daisetsu Avatar answered Jan 29 '26 06:01

Daisetsu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!