How to do Salt + Hash the password with SHA256 in AES cryptographic algorithm?

Prabs 1 Reputation point
2021-07-08T10:19:07.727+00:00

Hello Team,

I have an application with AES(The Advanced Encryption Standard (AES)) Password cryptographic algorithm logics.
How to do Salt + Hash the password with SHA256 in the following code.
Please help me on this?

This code i got it from the following link,
https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-5.0

using System;
using System.IO;
using System.Security.Cryptography;

namespace Aes_Example
{
class AesExample
{
public static void Main()
{
string original = "Here is some data to encrypt!";

        // Create a new instance of the Aes  
        // class.  This generates a new key and initialization  
        // vector (IV).  
        using (Aes myAes = Aes.Create())  
        {  

            // Encrypt the string to an array of bytes.  
            byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);  

            // Decrypt the bytes to a string.  
            string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);  

            //Display the original data and the decrypted data.  
            Console.WriteLine("Original:   {0}", original);  
            Console.WriteLine("Round Trip: {0}", roundtrip);  
        }  
    }  
    static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)  
    {  
        // Check arguments.  
        if (plainText == null || plainText.Length <= 0)  
            throw new ArgumentNullException("plainText");  
        if (Key == null || Key.Length <= 0)  
            throw new ArgumentNullException("Key");  
        if (IV == null || IV.Length <= 0)  
            throw new ArgumentNullException("IV");  
        byte[] encrypted;  

        // Create an Aes object  
        // with the specified key and IV.  
        using (Aes aesAlg = Aes.Create())  
        {  
            aesAlg.Key = Key;  
            aesAlg.IV = IV;  

            // Create an encryptor to perform the stream transform.  
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);  

            // Create the streams used for encryption.  
            using (MemoryStream msEncrypt = new MemoryStream())  
            {  
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))  
                {  
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))  
                    {  
                        //Write all data to the stream.  
                        swEncrypt.Write(plainText);  
                    }  
                    encrypted = msEncrypt.ToArray();  
                }  
            }  
        }  

        // Return the encrypted bytes from the memory stream.  
        return encrypted;  
    }  

    static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)  
    {  
        // Check arguments.  
        if (cipherText == null || cipherText.Length <= 0)  
            throw new ArgumentNullException("cipherText");  
        if (Key == null || Key.Length <= 0)  
            throw new ArgumentNullException("Key");  
        if (IV == null || IV.Length <= 0)  
            throw new ArgumentNullException("IV");  

        // Declare the string used to hold  
        // the decrypted text.  
        string plaintext = null;  

        // Create an Aes object  
        // with the specified key and IV.  
        using (Aes aesAlg = Aes.Create())  
        {  
            aesAlg.Key = Key;  
            aesAlg.IV = IV;  

            // Create a decryptor to perform the stream transform.  
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);  

            // Create the streams used for decryption.  
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))  
            {  
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))  
                {  
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))  
                    {  

                        // Read the decrypted bytes from the decrypting stream  
                        // and place them in a string.  
                        plaintext = srDecrypt.ReadToEnd();  
                    }  
                }  
            }  
        }  

        return plaintext;  
    }  
}  

}

Regards,
Prabs

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,412 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,205 questions
.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,117 questions
{count} votes

4 answers

Sort by: Most helpful
  1. PatriceSc 166 Reputation points
    2021-07-08T12:15:25.277+00:00

    Hi,
    Still a bit unclear. My understanding is that your app is currently encrypting the password and that you want to hash it instead?

    ASP.NET Identity handles this among other things for you and I would suggest to use that rather than rolling your own. See exploring-the-asp-net-core-identity-passwordhasher for the password hasher mechanism and more generally identity

    Edit: what if using Convert.ToBase64String(encrypted) to see the encrypted value and see if it is the same on each run? From your latest comments, my understanding is that you don't want the same value to produce always the same encrypted value which this code should do already.

    As pointed already don't confuse encryption and hashing (hashing is not supposed to be reversible and is preferred for passwords).

    0 comments No comments

  2. Prabs 1 Reputation point
    2021-07-09T07:15:21.417+00:00

    Hi PatriceSc-5382,

    The above code which is not included salt with password.
    I want to add salt with plaintext for encryption process. At the receiver end he has to remove the salt and decrypt it

    Example:

    Password – user123
    Salt - 8 bytes (any text)
    Salted Hash - user123 + 8 bytes character

    Regards
    Prabhakaran


  3. Xiaopo Yang - MSFT 11,256 Reputation points Microsoft Vendor
    2021-07-09T08:35:52.95+00:00

    Perhaps The initialization vector (IV) is The Salt you mean.

    (IV) A sequence of random bytes appended to the front of the plaintext before encryption by a block cipher. Adding the initialization vector to the beginning of the plaintext eliminates the possibility of having the initial ciphertext block the same for any two messages. For example, if messages always start with a common header (a letterhead or "From" line) their initial ciphertext would always be the same, assuming that the same cryptographic algorithm and symmetric key was used. Adding a random initialization vector eliminates this from happening.

    The Encrypting Data with CNG Sample.


  4. 陶祖洪 1 Reputation point
    2021-08-05T02:27:54.26+00:00
    public void initialize(string key, string salt)
            {
                m_user_key = key;
                m_user_salt = salt;
    
                // set cipher key(mixed user key with salt)
                var salt_bytes = Encoding.ASCII.GetBytes(salt);
                Rfc2898DeriveBytes key_with_salt = new Rfc2898DeriveBytes(key, salt_bytes, 1000);
                m_cipher.Key = key_with_salt.GetBytes(16);
    
                // set cipher iv
                m_cipher.GenerateIV();
            }
    
    0 comments No comments