Kicking System.Web out of your code – part 3: utilities

Last part of my blog posts about getting rid of System.Web.

We are going to look into some pretty gluing parts of System.Web now.

1. HtmlEncode & UrlEncode

This one is pretty easy, System.Net is actually coming with System.Web equivalents methods here.

2. Querystring value access

Same for easiness here, based on Rick Strahl’s extensions found here.

3. MachineKey

This one gets a litle more tricky, but looking around can bring you a replacement, as the one below:

public class LogrrMachineKey
{
    private static string _decryption = "AES";

    private static byte[] _cryptKey;
    private static string _decryptionKey;

    public static string DecryptionKey
    {
        set
        {
            _decryptionKey = value;
            var key = HexStringToByteArray(_decryptionKey);
            _cryptKey = key;
        }
    }

    public static byte[] Encrypt(byte[] inputBuffer)
    {
        SymmetricAlgorithm algorithm;
        byte[] outputBuffer;

        if (inputBuffer == null)
        {
            throw new ArgumentNullException("inputBuffer");
        }

        algorithm = GetCryptAlgorithm();

        using (var ms = new MemoryStream())
        {
            algorithm.GenerateIV();
            ms.Write(algorithm.IV, 0, algorithm.IV.Length);

            using (var cs = new CryptoStream(ms, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(inputBuffer, 0, inputBuffer.Length);
                cs.FlushFinalBlock();
            }
            outputBuffer = ms.ToArray();
        }
        return outputBuffer;
    }

    public static byte[] Decrypt(byte[] inputBuffer)
    {
        SymmetricAlgorithm algorithm;
        byte[] inputVectorBuffer, outputBuffer;

        if (inputBuffer == null)
            throw new ArgumentNullException("inputBuffer");

        algorithm = GetCryptAlgorithm();
        outputBuffer = null;

        try
        {
            inputVectorBuffer = new byte[algorithm.IV.Length];
            Array.Copy(inputBuffer, inputVectorBuffer, inputVectorBuffer.Length);
            algorithm.IV = inputVectorBuffer;

            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, algorithm.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputBuffer, inputVectorBuffer.Length, inputBuffer.Length - inputVectorBuffer.Length);
                    cs.FlushFinalBlock();
                }
                outputBuffer = ms.ToArray();
            }
        }
        catch (FormatException e)
        {
            throw new CryptographicException("The string could not be decoded.", e);
        }
        return outputBuffer;
    }

    private static SymmetricAlgorithm GetCryptAlgorithm()
    {
        SymmetricAlgorithm algorithm;
        string algorithmName;

        algorithmName = _decryption;
        if (algorithmName == "Auto")
        {
            throw new Exception("Explicit algorithm is required");
        }

        switch (algorithmName)
        {
            case "AES":
                algorithm = new RijndaelManaged();
                break;
            case "3DES":
                algorithm = new TripleDESCryptoServiceProvider();
                break;
            case "DES":
                algorithm = new DESCryptoServiceProvider();
                break;
            default:
                throw new Exception($"Algorithm {algorithmName} is not recognized");
        }

        algorithm.Key = _cryptKey;

        return algorithm;
    }

    private static byte[] HexStringToByteArray(string str)
    {
        byte[] buffer;

        if (str == null)
            throw new ArgumentNullException("str");

        if (str.Length % 2 == 1)
            str = '0' + str;

        buffer = new byte[str.Length / 2];

        for (int i = 0; i < buffer.Length; ++i)
        {
            buffer[i] = byte.Parse(str.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
        }
        return buffer;
    }
}

This class is not a one-to-one replacement of the existing MachineKey classes found in System.Web, so please make sure you migrate/ reset your values first.

Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *