Hash type and usage in .net core

Hash is an algorithm that converts data of arbitrary length into a fixed-length numeric value, also known as hashing or digesting. Hash can be used to ensure data integrity, verify digital signatures, generate passwords and other scenarios. In .NET Core, there are various types and usages of Hash algorithms, and this article will introduce some common examples.

1. Use the classes under the System.Security.Cryptography namespace to generate and verify Hash

.NET Core provides a series of classes under the System.Security.Cryptography namespace to support different types of Hash algorithms, such as SHA1, SHA256, SHA384, SHA512, MD5, etc. These classes all implement the abstract base class HashAlgorithm and therefore have the same basic methods and properties. For example:

  • HashData(byte[] data): Accepts a byte array as a parameter and returns a byte array as a Hash value.

  • ComputeHash(Stream inputStream): Accepts a stream object as a parameter and returns a byte array as a Hash value.

  • ComputeHash(byte[] buffer): Accepts a byte array as a parameter and returns a byte array as a Hash value.

  • ComputeHash(byte[] buffer, int offset, int count): Accepts a byte array, offset and length as parameters, and returns a byte array as the Hash value.

To use these classes to generate and verify hash values, you can follow these steps:

  1. Create an object instance of the corresponding type, such as SHA256 sha256 = SHA256.Create();

  1. Call one of the ComputeHash methods or the static method HashData to obtain the Hash value of the data, and convert it to a hexadecimal string or other formats for storage or transmission.

  1. When data integrity needs to be verified, the data is hashed again in the same type and manner and compared to the previously stored or transmitted hash. If the two are the same, it means that the data has not been tampered with; if they are different, it means that the data has been modified.

Here is an example code that hashes a string using SHA256 and verifies its integrity:

using System;
using System. Text;
using System.Security.Cryptography;

classProgram
{
    static voidMain(string[] args)
    {
        //Original string string originalString = "Hello world!";
        //Convert the string to a byte array byte[] originalBytes = Encoding.UTF8.GetBytes(originalString);
        //Create a SHA256 object instance
        SHA256 sha256 = SHA256. Create();
        // Calculate the hash value of the original string and convert it to a hexadecimal string byte[] hashBytes = sha256.ComputeHash(originalBytes);
        string hashString = Convert. ToHexString(hashBytes);
        Console.WriteLine($"The hash value of {originalString} is {hashString}");

        //Simulate modifying the original string string modifiedString = "Hello World!";
        byte[] modifiedBytes = Encoding.UTF8.GetBytes(modifiedString);
        // Calculate the hash value of the modified string and convert it to a hexadecimal string byte[] modifiedhashBytes = sha256.ComputeHash(modifiedBytes);
        string modifiedhashString = Convert.ToHexString(modifiedhashBytes);
        
        //Comparing whether the two hash values are the same if (hashString == modifiedhashString)
            Console.WriteLine("The data has not been altered.");
         else
            Console.WriteLine("The data has been altered.");
    }
}

The output is as follows:

The hash value of Hello world! is A591A6D40BF420404A011733CFB7B190D62C65BF0BCDA32B57B277D9AD9F146E
The data has been altered.

2. Use the System.HashCode structure to generate and verify non-encrypted hash codes

In addition to the above-mentioned encrypted hash code, there is also a non-cryptographic hash code (non-cryptographic hash code) structure System.HashCode in .NET Core, which can be used to generate a 32-bit or 64-bit hash Column code, used to quickly compare the equality of data or as the key value of the hash table. System.HashCode is not suitable for cryptographic scenarios as it is not secure nor stable (may produce different results on different runtimes or platforms). To generate and verify a hash code using System.HashCode, you can follow these steps:

  1. Create a System.HashCode object instance, and call the Add method to add data. The Add method can accept various types of parameters, such as int, string, bool, etc., and can be called in chains.

  1. Call the ToHashCode method to get a 32-bit or 64-bit (depending on the platform) hash code, and convert it to a hexadecimal string or other formats for storage or transmission.

  1. When data integrity needs to be verified, the data is hashed the same way again and compared to the previously stored or transmitted hash. If the two are the same, it means that the data has not been tampered with; if they are different, it means that the data has been modified.

Here is a sample code that uses System.HashCode to hash a string and verify its integrity:

using System;

classProgram
{
    static voidMain(string[] args)
    {
        //Original string string originalString = "Hello world!";
        //Create a HashCode object instance and add the original string
        HashCode hashCode = new HashCode();
        hashCode. Add(originalString);
        // Calculate the hash value of the original string and convert it to a hexadecimal string int hashValue = hashCode.ToHashCode();
        string hashString = hashValue. ToString("X");
        Console.WriteLine($"The hash value of {originalString} is {hashString}");

        //Simulate modifying the original string string modifiedString = "Hello World!";
        //Create a HashCode object instance and add the modified string
        HashCode modifiedhashCode = new HashCode();
        modifiedhashCode. Add(modifiedString);
        // Calculate the hash value of the modified string and convert it to a hexadecimal string int modifiedhashValue = modifiedhashCode.ToHashCode();
        string modifiedhashString = modifiedhashValue.ToString("X");

         //Comparing whether the two hash values are the same if (hashString == modifiedhashString)
            Console.WriteLine("The data has not been altered.");
         else
            Console.WriteLine("The data has been altered.");
    }
}

The output is as follows:

The hash value of Hello world! is 7F5B54CE
The data has been altered.

3. Use the System.Buffers.Text.Base64 class to perform Base64 encoding and decoding on byte arrays

Base64 is an encoding method that converts binary data into printable character (ASCII) format, and is often used to transmit binary data in text protocols. Base64 encoding will increase the length of the original data by about 33%, but it can guarantee correct transmission and parsing in any environment. In .NET Core, there are many ways to base64 encode and decode byte arrays, such as using the Convert class or the Encoding class. This article will introduce a new class introduced in .NET Core 2.1: System.Buffers.Text.Base64, which provides more efficient and flexible processing of Base64 encoding and decoding.

To Base64 encode and decode a byte array using the System.Buffers.Text.Base64 class, you can follow these steps:

  1. Create a byte array as source data, for example byte[] sourceBytes = Encoding.UTF8.GetBytes(“Hello world!”);

  1. Call the static method TryEncodeToUtf8 to convert the source byte array into a Base64-encoded byte array, and specify the target array, whether to insert newline characters, whether to fill placeholders and other parameters. The TryEncodeToUtf8 method returns a bool value indicating whether the encoding is successful, and returns the length of the encoded byte array through the out parameter. 4. Call the static method TryDecodeFromUtf8 to convert the Base64-encoded byte array to the original byte array, and specify the target array and other parameters. The TryDecodeFromUtf8 method returns a bool value indicating whether the decoding is successful, and returns the length of the decoded byte array through the out parameter. 5. When it is necessary to verify the integrity of the data, perform Base64 encoding or decoding on the data in the same way again, and compare it with the data stored or transmitted before. If the two are the same, it means that the data has not been tampered with; if they are different, it means that the data has been modified.

The following is a sample code that uses the System.Buffers.Text.Base64 class to Base64 encode and decode a byte array and verify its integrity:

using System;
using System. Text;
using System. Buffers. Text;

classProgram
{
    static voidMain(string[] args)
    {
        //Original string string originalString = "Hello world!";
        //Convert the string to a byte array byte[] originalBytes = Encoding.UTF8.GetBytes(originalString);
        //Create a target array large enough to store the Base64-encoded byte array byte[] encodedBytes = newbyte[originalBytes.Length * 2];
        //Call the TryEncodeToUtf8 method to convert the original byte array into a Base64-encoded byte array without inserting newlines or filling placeholders bool encodeSuccess = Base64.TryEncodeToUtf8(originalBytes, encodedBytes, outint encodedLength, false);
        //Judge whether the encoding is successful, and output the result to the console if (encodeSuccess)
            Console.WriteLine($"The Base64 encoded value of {originalString} is {Encoding.UTF8.GetString(encodedBytes)}");
         else
            Console.WriteLine("Failed to encode.");

         //Simulate modifying the original string string modifiedString = "Hello World!";
         byte[] modifiedBytes = Encoding.UTF8.GetBytes(modifiedString);
         // Create a target array large enough to store the Base64-encoded byte array byte[] modifiedEncodedBytes = newbyte[modifiedBytes.Length * 2];
         //Call the TryEncodeToUtf8 method to convert the modified byte array to a Base64-encoded byte array without inserting newlines or filling placeholders bool modifiedEncodeSuccess = Base64.TryEncodeToUtf8(modifiedBytes, modifiedEncodedBytes, outint modifiedEncodedLength, false);

         // Compare two Base64-encoded byte arrays for the same if (encodeSuccess & amp; & amp; modifiedEncodeSuccess & amp; & amp; encodedLength == modifiedEncodedLength)
            Console.WriteLine("The data has not been altered.");
         else
            Console.WriteLine("The data has been altered.");
    }
}

The output is as follows:

The Base64 encoded value of Hello world! is SGVsbG8gd29ybGQh
The data has been altered.